Максимальные месячные значения при сохранении данных, при которых эти значения имели место - PullRequest
0 голосов
/ 31 января 2019

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

   Date           Rainfall (mm) 
1922-01-01        0.0 
1922-01-02        0.0 
1922-01-03        0.0
1922-01-04        0.0
1922-01-05        31.5
1922-01-06        0.0
1922-01-07        0.0
1922-01-08        0.0
1922-01-09        0.0
1922-01-10        0.0
1922-01-11        0.0
1922-01-12        9.1
1922-01-13        6.4 

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

rain_data.groupby(pd.Grouper(freq = 'M'))['Rainfall (mm)'].max()

Это возвращает правильное максимальное значение, но возвращает дату окончания каждого месяца, а не дату, когда произошло максимальное событие.

1974-11-30 0,0



Я также пытался использовать .idxmax (), но это также просто возвращает конечные значения каждого месяца.

Любые предложения о том, как я могу получить правильную дату

1 Ответ

0 голосов
/ 31 января 2019

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'))
...