Создать новый скользящий средний столбец с GroupBy на нескольких столбцах - PullRequest
0 голосов
/ 21 января 2020

У меня есть фрейм данных с 11 столбцами, один из которых date является индексом. Я пытаюсь создать новый столбец со скользящим средним для столбца total. Тем не менее я получаю сообщение об ошибке: TypeError: несовместимый индекс вставленного столбца с индексом кадра

import pandas as pd

df = pd.DataFrame({
    'date':['2016-04-01','2016-05-01','2016-07-01','2016-08-01','2016-09-01',  '2019-04-01','2019-05-01','2019-06-01','2019-08-01','2019-09-01'],
    'Country':['USA', 'USA', 'USA', 'USA', 'USA','USA', 'USA', 'USA', 'USA', 'USA'],
    'Region':['Eastern','Eastern','Eastern','Eastern','Eastern','Eastern','Eastern','Eastern','Eastern','Eastern'],
    'State':['New York','New York','New York','New York','New York','New York','New York','New York','New York','New York'],
    'Supplier':['ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC','ABC'],
    'Location':['Bin-1', 'Bin-1', 'Bin-1', 'Bin-1', 'Bin-1','Bin-1', 'Bin-1', 'Bin-1', 'Bin-1', 'Bin-1'],
    'Year':[2016,2016,2016,2016,2016,2019,2019,2019,2019,2019],
    'Month':[4,5,7,8,9,4,5,6,8,9],
    'periodcode':[4,5,7,8,9,4,5,6,8,9],
    'Product':['bike','bike','bike','bike','bike','bike','bike','bike','bike','bike'],
    'total':[0,2000,1000,4000,0,2000,2000,1000,4000,600]})
df.set_index('date', inplace=True)

df['mean'] = df.groupby(['Country','Region','State','Supplier','Location','Product'], as_index=False)['total'].rolling(3).mean().reset_index(level=0,drop=True)
df.head(10)

Однако, когда я включаю столбец year в groupby, то есть

df['mean'] = df.groupby(['Country','Region','State','Supplier','Location','Product','Year'], as_index=False)['total'].rolling(3).mean().reset_index(level=0,drop=True) 

Я рассчитываю скользящее среднее. Проблема в том, что я хочу, чтобы группировка исключала Year

Есть идеи?

1 Ответ

0 голосов
/ 21 января 2020

Так как в нашем обсуждении в комментариях ниже вы хотели бы рассчитать скользящее среднее значение для группы по годам, следующее должно дать вам желаемый результат:

df['mean'] = df.groupby(['Country','Region','State','Supplier','Location','Product'])['total'].rolling(3).mean().reset_index().set_index("date")['total']

Ключ в том, чтобы сохранить date индекс (который позволяет сопоставить вычисленное скользящее среднее с строкой в ​​исходном кадре данных) и извлечь объект Series, возвращенный из расчета скользящего среднего по столбцу total.

Подробнее объяснение:

Ваша проблема в том, что groupby без Year приводит к DataFrame, который несовместим с df и, следовательно, не может быть назначен на df["mean"].

Первый вариант дает Series индекс совпадения ведьм:

df.groupby(['Country','Region','State','Supplier','Location','Product','Year'], as_index=False)['total'].rolling(3).mean().reset_index(level=0,drop=True)

date
2016-04-01            NaN
2016-05-01            NaN
2016-07-01    1000.000000
2016-08-01    2333.333333
2016-09-01    1666.666667
2019-04-01            NaN
2019-05-01            NaN
2019-06-01    1666.666667
2019-08-01    2333.333333
2019-09-01    1866.666667
Name: total, dtype: float64

Однако второй вариант (без Year) приводит к DataFrame, где каждая из записей в date column становится собственным столбцом. Следовательно, вы не можете присвоить его df["mean"].

Решение этой проблемы действительно зависит от проблемы, которую вы пытаетесь решить. Тем не менее, концептуально, если у вас date в качестве индекса, может быть только одно значение для каждого date в Series, который вы присваиваете df["mean"].

...