Как пересчитать временной ряд по заданным нерегулярным датам - PullRequest
2 голосов
/ 19 июня 2020
import pandas as pd
date_index = pd.date_range("2010-01-31", "2010-12-31", freq="M")
df  = pd.Series(range(12), index=date_index)

dates = date_index[1::2]

Серия df имеет ежемесячную частоту, и мы хотим выполнить повторную выборку, добавив значение между датами, заданное переменной dates.

df это:

2010-01-31     0
2010-02-28     1
2010-03-31     2
2010-04-30     3
2010-05-31     4
2010-06-30     5
2010-07-31     6
2010-08-31     7
2010-09-30     8
2010-10-31     9
2010-11-30    10
2010-12-31    11
Freq: M, dtype: int64

dates is

DatetimeIndex(['2010-02-28', '2010-04-30', '2010-06-30', '2010-08-31',
               '2010-10-31', '2010-12-31'],
              dtype='datetime64[ns]', freq='2M')

Ожидаемый результат должен быть:

2010-02-28     1
2010-04-30     5
2010-06-30     9
2010-08-31     13
2010-10-31     17
2010-12-31    21

Ответы [ 3 ]

2 голосов
/ 19 июня 2020

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

res = df.cumsum()[dates].diff()
res[0] = df[dates[0]]
res = res.astype(df.dtype)

Результат:

2010-02-28     1
2010-04-30     5
2010-06-30     9
2010-08-31    13
2010-10-31    17
2010-12-31    21
1 голос
/ 19 июня 2020

Для вашего конкретного примера c, где df[0] = 0, это простое resample с агрегированием sum(), пропуская df[0].

df_resampled = df[1::].resample('2M').sum()

print(df_resampled)
2010-02-28     1
2010-04-30     5
2010-06-30     9
2010-08-31    13
2010-10-31    17
2010-12-31    21
Freq: 2M, dtype: int64

В case df[0] != 0, вы все равно можете найти простой обходной путь, добавив df[0] к первому элементу df_resampled:

df_resampled[0] = df_resampled[0] + df[0]

. Если вам нужна общая передискретизация с периодом в два месяца, вы можете попробовать использовать параметр loffset из resample и предоставить функцию, возвращающую pd.Timedelta объектов, таким образом, чтобы она «перекрывала» последний день каждого отдельного месяца. (См. здесь , чтобы узнать, как получить месячные периоды для pd.Timedelta)

1 голос
/ 19 июня 2020

Идея заключается в замене несоответствующих значений date s на отсутствующие значения на Series.where на bfill для заполнения отсутствующих значений bacj с последующим агрегированием sum:

date_index = pd.date_range("2010-01-31", "2010-12-31", freq="M")
s  = pd.Series(range(12), index=date_index)

dates = date_index[1::2]

a = s.index.to_series().where(s.index.isin(dates)).bfill()
out = s.groupby(a).sum()
print(out)
2010-02-28     1
2010-04-30     5
2010-06-30     9
2010-08-31    13
2010-10-31    17
2010-12-31    21
dtype: int64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...