Вычисление среднего для групп строк-столбцов 2x2 для DataFrame - PullRequest
2 голосов
/ 24 сентября 2019

У меня есть DataFrame, для которого я хотел бы взять несколько средств и вывести один Series / DataFrame для.

Я бы хотел, чтобы каждое среднее было сгруппировано по срезу 2x2 всего DataFrame.

Примером этого может быть:

df = pd.DataFrame({'0' : [4, 5, 6, 7, 8, 10], '1' : [2, 0, 1, 2, 3, 4],
                   '2' : [2, 4, 6, 8, 10, 12]}).T

df_mean

2.75
3
4
5
.
.
5.75
7.25

Способ, которым будет группироваться, взяв первые строки 2x2 'slice' ([4, 5], [2, 0]) рассчитать среднее(4+5+2+0)/4 = 2.75, затем повторяйте это для каждого среза до следующей строки, пока все возможные срезы 2x2 не будут рассчитаны по всем строкам.

Т.е.:

([5, 6], [0, 1]).mean() = 3
([6, 7], [1, 2]).mean() = 4
.
.
.
([3, 4], [10, 12]).mean() = 7.25

Я могу только вычислитьо том, как сгруппировать 2 вниз по строке и взять среднее значение:

df_mean = df.groupby(np.arange(len(df)) // 2).mean()

Но это только сгруппирует по 2 вниз по каждому столбцу, а не по 2x2 «ячейке».

Есть ли способиспользовать groupby, чтобы сделать это?Я стараюсь избегать вычислительно дорогостоящих циклов for для индексов строк и столбцов, если это возможно.

Ответы [ 2 ]

4 голосов
/ 24 сентября 2019

Я использую rolling, mean и dropna вдоль двух осей, чтобы получить желаемый результат:

import pandas as pd

df = pd.DataFrame(
    {'0': [4, 5, 6, 7, 8, 10], '1': [2, 0, 1, 2, 3, 4], '2': [2, 4, 6, 8, 10, 12]}
).T
mean_df = (
    df.rolling(2)
    .mean()
    .dropna(how='all')
    .rolling(2, axis='columns')
    .mean()
    .dropna(how='all', axis='columns')
)
print(mean_df)

      1     2     3     4     5
1  2.75  3.00  4.00  5.00  6.25
2  2.00  2.75  4.25  5.75  7.25

Роллинг создает окна, в которыхсреднее значение вычисляется, dropna удаляет строки, в которых есть значения NaN, когда окна принимают значения за пределами кадра данных.

1 голос
/ 24 сентября 2019

Если все ваши данные относятся к одному типу, вы можете использовать as_strided:

size = (2,2)

from numpy.lib.stride_tricks import as_strided

strides = df.values.strides

new_rows = (df.shape[0] - size[0] + 1) 
new_cols = (df.shape[1] - size[1] + 1)

array = as_strided(df.values, 
                   (size[0],size[1], new_rows, new_cols), 
                   [strides[0], strides[1], strides[0], strides[1]])

np.mean(array,
        axis=(0,1))

Выход:

array([[2.75, 3.  , 4.  , 5.  , 6.25],
   [2.  , 2.75, 4.25, 5.75, 7.25]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...