Получить среднемесячное значение в pandas

#python #pandas #dataframe #datetime

#python #pandas #фрейм данных #дата и время

Вопрос:

У меня есть следующие временные ряды:

         Date        Value
0       2006-01-03  18
1       2006-01-04  12
2       2006-01-05  11
3       2006-01-06  10
4       2006-01-09  22
...     ...     ...
3510    2019-12-23  47
3511    2019-12-24  46
3512    2019-12-26  35
3513    2019-12-27  35
3514    2019-12-30  28
 

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

  1. Суммируйте все значения для каждого дня, присутствующего в этом месяце
  2. Разделите на количество дней с данными за этот месяц.

Желаемый результат будет чем-то похожим на:

         Date        Value
0       2006-01     17.45
1       2006-02     18.23
2       2006-04     16.79
3       2006-05     17.98
...     ...     ...
166     2019-11     37.89
167     2019-12     36.34
 

Я пробовал это без успеха:

 data = data.set_index('Date')
data.resample('M')

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-28-435afe449f1f> in <module>
     47 data = pd.DataFrame(dataList, columns=('Date', 'Value'))
     48 data = data.set_index('Date')
---> 49 data.resample('M')
 

Ответ №1:

Мы можем преобразовать ваш столбец даты и времени в PeriodIndex ежемесячную частоту, а затем получить среднее значение, используя GroupBy.mean :

 df.groupby(pd.PeriodIndex(df['Date'], freq="M"))['Value'].mean()
    
Date
2006-01    14.6
2019-12    38.2
Freq: M, Name: Value, dtype: float64
 

 df.groupby(pd.PeriodIndex(df['Date'], freq="M"))['Value'].mean().reset_index()

      Date  Value
0  2006-01   14.6
1  2019-12   38.2
 

Одним из недостатков этого подхода является то, что пропущенные месяцы не отображаются. Если это важно, используйте set_index и resample.mean таким же образом.

Комментарии:

1. Поправьте меня, если я ошибаюсь, но я думаю, что days_in_month учитывает все естественные дни в конкретном месяце, но у меня нет данных за каждый день

2. @M.E. извиняюсь, неправильно понял вопрос. Пожалуйста, посмотрите редактирование здесь.

Ответ №2:

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

data_month = data.resample('M', on='Date').mean()

Пожалуйста, обратите внимание, что сама повторная выборка сама по себе не справляется с задачей. Требуется .mean() .

Подробнее о документации 🙂

Комментарии:

1. Я пытаюсь это сделать и получаю: TypeError: допустимо только для DatetimeIndex, TimedeltaIndex или PeriodIndex, но получил экземпляр ‘Index’

2. хорошо, тогда, пожалуйста, убедитесь, что ваш столбец «Дата» имеет тип Datetime. Что-то вроде data.Date = pd.to_datetime(data.Date)

3. @cs95 на самом деле я хочу разделить на количество строк в месяц, а не на естественные дни месяца (в случае, если это неясно в исходном вопросе)

4. Я выбрал ответ @ cs95, но этот ответ на самом деле довольно верный, и я добавляю его в закладки, поскольку нахожу его очень полезным