pandas: скользящее среднее по временному интервалу плюс группировка по индексу - PullRequest
0 голосов
/ 16 апреля 2020

Я пытаюсь найти 7-дневное скользящее среднее для часа дня для категории. Фрейм данных индексируется по идентификатору категории, и есть отметка времени плюс другие столбцы:

    id   name  ds  time              x    y   z
    6    red   2020-02-14 00:00:00   10   20  30 
    6    red   2020-02-14 01:00:00   20   40  50 
    6    red   2020-02-14 02:00:00   20   20  60 
...
    6    red   2020-02-21 00:00:00   20   30  60 
    6    red   2020-02-21 01:00:00   20   40  60 
    6    red   2020-02-21 02:00:00   10   40  60 
    7    green   2020-02-14 00:00:00   10   20  30 
    7    green   2020-02-14 01:00:00   20   40  50 
    7    green   2020-02-14 02:00:00   20   20  60 
...
    7    green   2020-02-21 00:00:00   20   30  60 
    7    green   2020-02-21 01:00:00   20   40  60 
    7    green   2020-02-21 02:00:00   10   40  60 

, что я хотел бы получить в качестве вывода (очевидно, когда скользящие столбцы заполнены скользящим средним, где не NaN) :

id   name  ds  time              x    y   z   rolling_x  rolling_y  rolling_z
6    red   2020-02-14 00:00:00   10   20  30    NaN       NaN        NaN
6    red   2020-02-14 01:00:00   20   40  50    NaN       NaN        NaN
6    red   2020-02-14 02:00:00   20   20  60    NaN       NaN        NaN
...
 6    red   2020-02-21 00:00:00   20   30  60    
 6    red   2020-02-21 01:00:00   20   40  60 
 6    red   2020-02-21 02:00:00   10   40  60 
 7    green   2020-02-14 00:00:00   10   20  30  NaN       NaN        NaN
 7    green   2020-02-14 01:00:00   20   40  50  NaN       NaN        NaN
 7    green   2020-02-14 02:00:00   20   20  60  NaN       NaN        NaN

...
 7    green   2020-02-21 00:00:00   20   30  60  
 7    green   2020-02-21 01:00:00   20   40  60 
 7    green   2020-02-21 02:00:00   10   40  60

1 Ответ

0 голосов
/ 16 апреля 2020

Мой подход:

df = df.assign(day=df['ds time'].dt.normalize(),
               hour=df['ds time'].dt.hour)

ret_df = df.merge(df.drop('ds time', axis=1)
           .set_index('day')
           .groupby(['id','hour']).rolling('7D').mean()
           .drop(['hour','id'], axis=1),
         on=['id','hour','day'],
         how='left',
         suffixes=['','_roll']
        ).drop(['day','hour'], axis=1)

Пример данных :

dates = pd.date_range('2020-02-21', '2020-02-25', freq='H')

np.random.seed(1)
df = pd.DataFrame({
    'id': np.repeat([6,7], len(dates)),
    'ds time': np.tile(dates,2),
    'X': np.arange(len(dates)*2),
    'Y': np.random.randint(0,10, len(dates)*2)
})
df.head()

Вывод ret_df.head():

   id             ds time  X  Y  X_roll  Y_roll
0   6 2020-02-21 00:00:00  0  5     0.0     5.0
1   6 2020-02-21 01:00:00  1  8     1.0     8.0
2   6 2020-02-21 02:00:00  2  9     2.0     9.0
3   6 2020-02-21 03:00:00  3  5     3.0     5.0
4   6 2020-02-21 04:00:00  4  0     4.0     0.0
...