pd.Grouper
, кажется, меняет порядок в группах на Datetime
, что нарушает обычный трюк .sort_values
+ .tail
.Вместо этого сгруппируйте по году и месяцу:
df.sort_values('Rainfall (mm)').groupby([df.Date.dt.year, df.Date.dt.month]).tail(1)
Пример данных + Вывод
import pandas as pd
import numpy as np
np.random.seed(123)
df = pd.DataFrame({'Date': pd.date_range('1922-01-01', freq='D', periods=100),
'Rainfall (mm)': np.random.randint(1,100,100)})
df.sort_values('Rainfall (mm)').groupby([df.Date.dt.month, df.Date.dt.year]).tail(1)
# Date Rainfall (mm)
#82 1922-03-24 92
#35 1922-02-05 98
#2 1922-01-03 99
#90 1922-04-01 99
Проблема с pd.Grouper
заключается в том, что он создает DatetimeIndex
с частотой конца месяца, которая нам на самом деле не нужна, и мы используем .apply
.Это даст вам новый индекс, и, тем не менее, он отсортирован по дате!
(df.groupby(pd.Grouper(key='Date', freq='1M'))
.apply(lambda x: x.loc[x['Rainfall (mm)'].idxmax()])
.reset_index(drop=True))
# Date Rainfall (mm)
#0 1922-01-03 99
#1 1922-02-05 98
#2 1922-03-24 92
#3 1922-04-01 99
Также можно с .drop_duplicates
, используя первые 7 символов даты, чтобы получить год-месяц
(df.assign(ym = df.Date.astype(str).str[0:7])
.sort_values('Rainfall (mm)')
.drop_duplicates('ym', keep='last')
.drop(columns='ym'))