【问题标题】:Pandas - Count frequency of value for next/upcoming x amount of daysPandas - 计算下一个/即将到来的 x 天数的价值频率
【发布时间】:2020-07-13 10:43:25
【问题描述】:

这是对我在这里提出的问题的跟进:Pandas - Count frequency of value for last x amount of days

我试图而不是在过去 x 天中计数,我希望计数查看 ID,并计算它在接下来的 x 天中显示的次数。例如,从给定的日期时间开始,ID 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 天窗口计数的方法。我已经尝试过相同的代码,但是在按日期降序排列之后,我认为只需切换顺序就可以了,但事实并非如此。所以我被困在如何让滚动窗口向前 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)

【问题讨论】:

  • 有点吹毛求疵:问题中的条件是show up in the next 7 days,预期结果列名称是count_in_last_7_days
  • 啊,很好。我会改变的

标签: python pandas datetime rolling-computation


【解决方案1】:

这是一个使用 groupby 和 apply 的方法。我感觉使用 groupby 和 transform 可能有更好的方法,但我从未使用过 transform 并且仍在尝试解决。

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() 表示不计算过去的日期。

【讨论】:

  • 这很棒。比我今天尝试的要好得多。我打算尝试获取日期的倒数,然后应用我之前使用的方法,然后将它们合并在一起以获得原始日期时间。
猜你喜欢
  • 2020-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-04
  • 2016-06-30
  • 2018-08-13
相关资源
最近更新 更多