这是我在这里提出的问题的后续措施:Pandas - Count frequency of value for last x amount of days
我想而不是在最近的x天内获得计数,我希望该计数可以查看ID,并计算在接下来的x天内显示的次数。例如,从给定的日期时间开始,在接下来的7天中ID A会出现多少次?因此,这就像反向滚动计数。
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)
答案 0 :(得分: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'
是日期时间dtypes。
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()
表示不计算过去的日期。