Скользящее окно со смещением даты «7d» для индекса даты и времени, отсортированного в обратном порядке - PullRequest
3 голосов
/ 27 июня 2019

У меня есть следующий набор данных, который сортируется по столбцам grp (по возрастанию), а затем по столбцам ts (по убыванию):

In [49]: df
Out[49]:
    id grp         ts
0    1   A 2018-12-30
1    2   A 2018-12-23
2    3   A 2018-12-22
3    4   A 2018-12-21
4    5   B 2018-11-11
5    6   B 2018-09-09
6    7   B 2018-09-03
7    8   B 2018-09-01
8    9   B 2018-08-01
9   10   C 2018-06-20
10  11   C 2018-06-17
11  12   C 2018-06-15
12  13   D 2018-01-01

Я хочу подсчитать строки в 7 dasys скользящее окно для каждой группы, где ts (отметка времени) упорядочено в в порядке убывания , чтобы я мог получить следующий требуемый набор данных :

   grp         ts count
0    A 2018-12-30    1
1    A 2018-12-23    2
2    A 2018-12-22    2
3    A 2018-12-21    3
4    B 2018-11-11    1
5    B 2018-09-09    1
6    B 2018-09-03    2
7    B 2018-09-01    2
8    B 2018-08-01    1
9    C 2018-06-20    1
10   C 2018-06-17    2
11   C 2018-06-15    3
12   D 2018-01-01    1

окно смещения даты работает не так, как ожидалось для индекса даты и времени, если оно отсортировано в порядке убывания:

In [56]: (df.set_index("ts")
            .groupby("grp")
            .rolling("7d", min_periods=1)
            .count()
            .reset_index()
            .rename(columns={"id":"count"}))
Out[56]:
   grp         ts  count
0    A 2018-12-30    1.0
1    A 2018-12-23    2.0
2    A 2018-12-22    3.0
3    A 2018-12-21    4.0
4    B 2018-11-11    1.0
5    B 2018-09-09    2.0
6    B 2018-09-03    3.0
7    B 2018-09-01    4.0
8    B 2018-08-01    5.0
9    C 2018-06-20    1.0
10   C 2018-06-17    2.0
11   C 2018-06-15    3.0
12   D 2018-01-01    1.0

Похоже, что окно "7d" игнорируется (не учитывается) ...

И если я сортирую индекс в порядке возрастания, то окно "7d" уважается, но дает мне нежелательные результаты:

In [57]: (df.sort_values("ts")
            .set_index("ts")
            .groupby("grp")
            .rolling("7d", in_periods=1)
            .count()
            .reset_index()
            .rename(columns={"id":"count"}))
Out[57]:
   grp         ts  count
0    A 2018-12-21    1.0
1    A 2018-12-22    2.0
2    A 2018-12-23    3.0
3    A 2018-12-30    1.0
4    B 2018-08-01    1.0
5    B 2018-09-01    1.0
6    B 2018-09-03    2.0
7    B 2018-09-09    2.0
8    B 2018-11-11    1.0
9    C 2018-06-15    1.0
10   C 2018-06-17    2.0
11   C 2018-06-20    3.0
12   D 2018-01-01    1.0

Вопрос: какполучаем ли мы нужный набор данных эффективным образом ?

PS Я не хочу использовать повторную выборку, поскольку мой реальный набор данных очень большой, и после повторной выборки я сомневаюсь, что он поместится в памяти...: (


Настройка для набора образцов данных:

import numpy as np
import pandas as pd
from pandas import Timestamp

data = np.array([
       [1, 'A', Timestamp('2018-12-30')],
       [2, 'A', Timestamp('2018-12-23')],
       [3, 'A', Timestamp('2018-12-22')],
       [4, 'A', Timestamp('2018-12-21')],
       [5, 'B', Timestamp('2018-11-11')],
       [6, 'B', Timestamp('2018-09-09')],
       [7, 'B', Timestamp('2018-09-03')],
       [8, 'B', Timestamp('2018-09-01')],
       [9, 'B', Timestamp('2018-08-01')],
       [10, 'C', Timestamp('2018-06-20')],
       [11, 'C', Timestamp('2018-06-17')],
       [12, 'C', Timestamp('2018-06-15')],
       [13, 'D', Timestamp('2018-01-01')]])

df = pd.DataFrame(data, columns=['id','grp','ts'])
df['ts'] = df['ts'].dt.floor('D')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...