Pandas передискретизирует временные ряды, считая в обратном порядке (или обратная передискретизация)

Я хочу пересчитать временной ряд панд, считая в обратном порядке. Например, давайте создадим простой временной ряд из 11 дней:

>>> index = pd.date_range('01-01-2018', '01-11-2018', freq='D')
>>> randint = np.random.randint(low=0, high=9, size=(len(index), 1))

>>> df = pd.DataFrame(randint, index=index, columns=['random'])
>>> print(df)

            random
2018-01-01       8
2018-01-02       8
2018-01-03       1
2018-01-04       4
2018-01-05       3
2018-01-06       5
2018-01-07       2
2018-01-08       6
2018-01-09       5
2018-01-10       1
2018-01-11       3

Поведение панд по умолчанию

Если я буду делать повторную выборку каждые 5 дней, то получу:

>>> df_5d = df.resample('5D').sum()
>>> print(df_5d)

            random
2018-01-01      24
2018-01-06      19
2018-01-11       3

Обычно у вас есть 3 группы: первые две группы состоят из 5 участников, а последняя группа - 1, всего 11 участников:

Start        End
2018-01-01   2018-01-05
2018-01-06   2018-01-10
2018-01-11   2018-01-11

Я хочу это

>>> df_5d = df.resample('5D').sum()
>>> print(df_5d)

            random
2018-01-01       8
2018-01-02      21
2018-01-07      17

И группы показаны ниже. Посмотрите, как я считал '5D' в обратном порядке, начиная с последней даты:

Start        End
2018-01-01   2018-01-01
2018-01-02   2018-01-06
2018-01-07   2018-01-11

Как мне пересчитать временные ряды панд, считая в обратном порядке?

Будут ли пропущены дни в ваших реальных данных?

GeorgeLPerkins 10.08.2018 16:06

Также см. stackoverflow.com/questions/37866145/…

GeorgeLPerkins 10.08.2018 16:11
4
2
1 124
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы могли бы использовать

In [452]: t = np.arange(len(df.index)-1, -1, -1) // 5

In [453]: df.reset_index().groupby(t, sort=False)['index'].agg([min, max])
Out[453]:
         min        max
2 2018-01-01 2018-01-01
1 2018-01-02 2018-01-06
0 2018-01-07 2018-01-11
Ответ принят как подходящий

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

res_interval = 5
df_res = pd.concat([df[:len(df)%res_interval].resample('{}D'.format(res_interval)).sum(),
                    df[len(df)%res_interval:].resample('{}D'.format(res_interval)).sum()])

и со своим случайным числом я получаю:

            random
2018-01-01       1
2018-01-02      13
2018-01-07      26

Думаю хорошее решение;)

jezrael 10.08.2018 16:37

Мне пришлось разобрать его и посмотреть, что именно вы делаете, но это действительно отличное решение. Вам действительно не нужно выполнять сэмплирование в обратном направлении, просто сэмплируйте блоки X-сегмента с модулем в начале. Это определенно должен быть принятый ответ, и он был сохранен в моих ссылках на проект.

GeorgeLPerkins 10.08.2018 17:26

Как это сделать для datetime с полными часами, минутами и секундами для ежечасной повторной выборки?

npm 18.07.2019 14:12

Думаю, у меня есть довольно простое решение:

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

index = pd.date_range('01-01-2018', '01-11-2018', freq='D')
randint = np.random.randint(low=0, high=9, size=(len(index), 1))

df = pd.DataFrame(randint, index=index, columns=['random'])
print(df)

            random
2018-01-01       0
2018-01-02       4
2018-01-03       6
2018-01-04       8
2018-01-05       3
2018-01-06       8
2018-01-07       3
2018-01-08       4
2018-01-09       5
2018-01-10       5
2018-01-11       4

С помощью label и closed = 'right' вы сообщаете resample, что первый день следует рассматривать в интервале суммированных значений и что он должен использоваться в качестве метки для индекса.

print(df.sort_index(ascending=False).resample('5D',label='right',closed='right').sum())

random
2018-01-01       0
2018-01-06      29
2018-01-11      21

Другие вопросы по теме