Странное поведение при использовании метода панд Групера с объектами datetime - PullRequest
0 голосов
/ 30 мая 2018

Я пытаюсь создать группы по x дней внутри групп другого столбца.По какой-то причине поведение группировки изменилось , когда я добавляю другой уровень группировки.

См. Пример с игрушкой ниже:

Создание случайного кадра данных с 40 последовательными датами, идентификаторомстолбец и случайные значения:

import numpy as np
import pandas as pd
df = pd.DataFrame(
        {'dates':pd.date_range('2018-1-1',periods=40,freq='D'),
         'id': np.concatenate((np.repeat(1,10),np.repeat(2,30))),
         'amount':np.random.random(40)
         }
)

Я хочу сначала сгруппировать по id, а затем создать группы, скажем, 7 последовательных дней в этих группах.Я делаю:

(df
 .groupby(['id',pd.Grouper(key='dates',freq='7D')])
 .amount
 .agg(['mean','count'])
)

И вывод:

                   mean  count
id dates                      
1  2018-01-01  0.591755      7
   2018-01-08  0.701657      3
2  2018-01-08  0.235837      4
   2018-01-15  0.650085      7
   2018-01-22  0.463854      7
   2018-01-29  0.643556      7
   2018-02-05  0.459864      5

Во второй группе происходит что-то странное!Я ожидаю увидеть 4 группы по 7, а затем последнюю группу из 2. Когда я запускаю один и тот же код на кадре данных только с id=2, я получаю то, что на самом деле ожидаю:

df2=df[df.id==2]

(df2
 .groupby(['id',pd.Grouper(key='dates',freq='7D')])
 .amount
 .agg(['mean','count'])
)

Вывод

                   mean  count
id dates                      
2  2018-01-11  0.389343      7
   2018-01-18  0.672550      7
   2018-01-25  0.486620      7
   2018-02-01  0.520816      7
   2018-02-08  0.529915      2

Что здесь происходит?Сначала создается группа из 4 в группе id=2, потому что последняя группа в группе id=1 состояла только из 3 строк?Это не то, что я хочу сделать!

1 Ответ

0 голосов
/ 30 мая 2018

Когда вы группируете с обоими идентификаторами, вы переходите из первой группы во вторую при выполнении еженедельного группового задания (потому что на прошлой неделе недостаточно дней, чтобы завершить полные 7 дней в группе № 1).Это очевидно, когда вы смотрите на первое свидание для каждой группы:

"2018-01-08" в первом случае v / s "2018-01-11".

Обходной путьgroupby выполнить id и затем apply операцию повторной выборки:

df.groupby('id').apply(
    lambda x: x.set_index('dates').amount.resample('7D').count()
)

id  dates     
1   2018-01-01    7
    2018-01-08    3
2   2018-01-11    7
    2018-01-18    7
    2018-01-25    7
    2018-02-01    7
    2018-02-08    2
Name: amount, dtype: int64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...