Pandas - частота подсчёта значения для следующего / следующего x количества дней - PullRequest
0 голосов
/ 01 апреля 2020

Это продолжение вопроса, который я задал здесь: Pandas - Частота подсчета значений за последние x дней

Я пытаюсь вместо того, чтобы получить посчитать последние x дней, я бы хотел, чтобы счетчик посмотрел на ID и посчитал, сколько раз он будет показан в x следующих днях. Так, например, сколько раз идентификатор A появляется в течение следующих 7 дней, начиная с указанной даты и времени подряд? Так что это похоже на обратный скользящий счет.

import pandas as pd




df = pd.DataFrame(
        [['A', '2020-02-02 20:31:00'],
        ['A', '2020-02-03 00:52:00'],
        ['A', '2020-02-07 23:45:00'],
        ['A', '2020-02-08 13:19:00'],
        ['A', '2020-02-18 13:16:00'],
        ['A', '2020-02-27 12:16:00'],
        ['A', '2020-02-28 12:16:00'],
        ['B', '2020-02-07 18:57:00'],
        ['B', '2020-02-07 21:50:00'],
        ['B', '2020-02-12 19:03:00'],
        ['C', '2020-02-01 13:50:00'],
        ['C', '2020-02-11 15:50:00'],
        ['C', '2020-02-21 10:50:00']],
        columns = ['ID', 'Date'])

df['Date'] = pd.to_datetime(df['Date'])

Желаемый результат:

   ID                Date  count_in_next_7_days
0   A 2020-02-02 20:31:00                     3
1   A 2020-02-03 00:52:00                     2
2   A 2020-02-07 23:45:00                     1
3   A 2020-02-08 13:19:00                     0
4   A 2020-02-18 13:16:00                     0
5   A 2020-02-27 12:16:00                     1
6   A 2020-02-28 12:16:00                     0
7   B 2020-02-07 18:57:00                     2
8   B 2020-02-07 21:50:00                     1
9   B 2020-02-12 19:03:00                     0
10  C 2020-02-01 13:50:00                     0
11  C 2020-02-11 15:50:00                     0
12  C 2020-02-21 10:50:00                     0

Вот как получить счет за предыдущие 7 дней windows. Я пробовал этот же код, но, прибегнув к дате в порядке убывания, подумал, что просто переключение порядка будет работать, но это не так. Так что я застрял в том, как заставить скользящее окно смотреть вперед на x дней, а не на x дней.

delta = 7
df = df[['ID','Date']]
df = (df.set_index('Date')
   .assign(count_last=1)
   .groupby('ID')
   .rolling(f'{delta}D')
   .sum() - 1).reset_index(drop=False)

1 Ответ

1 голос
/ 02 апреля 2020

Вот метод, использующий groupby и apply. У меня есть ощущение, что может быть лучший способ использования группового преобразования и преобразования, но я никогда не использовал преобразование и все еще пытаюсь выяснить это.

def f(thing):
    cutoff = thing.loc['Date'] + seven
    mask = group.loc[thing.name:,'Date'] <= cutoff
    return mask.sum() - 1

df = df.assign(count_in_next_7_days=0)
seven = pd.Timedelta('7 days')
grouped = df.groupby('ID')
for name,group in grouped:
    n = group.apply(f,axis=1)
    df.loc[df['ID'] == name,['count_in_next_7_days']] = n

Вот альтернативный вариант использования numpy сравнения с вещанием. Предполагается, что он отсортирован по дате, а 'Date' являются типами даты и времени.

df = df.assign(count_in_next_7_days=0)
ids = df.ID.unique()
for idee in ids:
    mask = df['ID'] == idee
    x = df.loc[mask,'Date'].values
    y = x + seven
    comparison = y[:,None] >= x
    counts = comparison.sum(1) - 1 - np.arange(x.shape[0])
    df.loc[mask,'count_in_next_7_days'] = counts

Для counts = comparison.sum(1) - 1 - np.arange(x.shape[0]) минус один для того, чтобы не считать сам , а минус .arange() для не считая прошедшие даты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...