Python 熊猫-最后x天数量的值计数频率
我发现了一些意想不到的结果。我试图做的是创建一个列,查看ID号和日期,并计算在过去7天内ID号出现的次数(我也想将该动态设置为x天,但仅用7天进行尝试) 因此,考虑到这个数据框架:Python 熊猫-最后x天数量的值计数频率,python,pandas,datetime,pandas-groupby,rolling-computation,Python,Pandas,Datetime,Pandas Groupby,Rolling Computation,我发现了一些意想不到的结果。我试图做的是创建一个列,查看ID号和日期,并计算在过去7天内ID号出现的次数(我也想将该动态设置为x天,但仅用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'],
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'])
用于计算每个实例在过去7天内发生的事件的代码:
df['Date'] = pd.to_datetime(df['Date'])
delta = 7
df['count_in_last_%s_days' %(delta)] = df.groupby(['ID', pd.Grouper(freq='%sD' %delta, key='Date')]).cumcount()
输出:
ID Date count_in_last_7_days
0 A 2020-02-02 20:31:00 0
1 A 2020-02-03 00:52:00 1
2 A 2020-02-07 23:45:00 2
3 A 2020-02-08 13:19:00 0 #<---- This should output 3
4 A 2020-02-18 13:16:00 0
5 A 2020-02-27 12:16:00 0
6 A 2020-02-28 12:16:00 1
7 B 2020-02-07 18:57:00 0
8 B 2020-02-07 21:50:00 1
9 B 2020-02-12 19:03:00 0 #<---- THIS SHOULD OUTPUT 2
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
count_last
ID Date
A 2020-02-02 20:31:00 0.0
2020-02-03 00:52:00 1.0
2020-02-07 23:45:00 2.0
2020-02-08 13:19:00 3.0
2020-02-18 13:16:00 0.0
2020-02-27 12:16:00 0.0
2020-02-28 12:16:00 1.0
B 2020-02-07 18:57:00 0.0
2020-02-07 21:50:00 1.0
2020-02-12 19:03:00 2.0
C 2020-02-01 13:50:00 0.0
2020-02-11 15:50:00 0.0
2020-02-21 10:50:00 0.0
ID日期计数(以最后7天为单位)
0A2020-02-0220:31:00
1A 2020-02-03 00:52:00 1
2A 2020-02-07 23:45:00 2
3 A 2020-02-08 13:19:00 0#您不希望在日期使用石斑鱼
,而是使用滚动窗口。grouper将在所需持续时间的单独连续块中分割数据帧。由于您希望从每个日期算起7天,这是滚动的工作:
delta = 7
df['count_in_last_%s_days' %(delta)] = df.assign(count=1).groupby(
['ID']).apply(lambda x: x.rolling('%sD' %delta, on='Date').sum(
))['count'].astype(int) - 1
正如预期的那样:
ID Date count_in_last_7_days
0 A 2020-02-02 20:31:00 0
1 A 2020-02-03 00:52:00 1
2 A 2020-02-07 23:45:00 2
3 A 2020-02-08 13:19:00 3
4 A 2020-02-18 13:16:00 0
5 A 2020-02-27 12:16:00 0
6 A 2020-02-28 12:16:00 1
7 B 2020-02-07 18:57:00 0
8 B 2020-02-07 21:50:00 1
9 B 2020-02-12 19:03:00 2
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
看起来像一个滚动的日期
,有正确的窗口可以:
(df.set_index('Date')
.assign(count_last=1)
.groupby('ID')
.rolling(f'{delta}D')
.sum() - 1
)
输出:
ID Date count_in_last_7_days
0 A 2020-02-02 20:31:00 0
1 A 2020-02-03 00:52:00 1
2 A 2020-02-07 23:45:00 2
3 A 2020-02-08 13:19:00 0 #<---- This should output 3
4 A 2020-02-18 13:16:00 0
5 A 2020-02-27 12:16:00 0
6 A 2020-02-28 12:16:00 1
7 B 2020-02-07 18:57:00 0
8 B 2020-02-07 21:50:00 1
9 B 2020-02-12 19:03:00 0 #<---- THIS SHOULD OUTPUT 2
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
count_last
ID Date
A 2020-02-02 20:31:00 0.0
2020-02-03 00:52:00 1.0
2020-02-07 23:45:00 2.0
2020-02-08 13:19:00 3.0
2020-02-18 13:16:00 0.0
2020-02-27 12:16:00 0.0
2020-02-28 12:16:00 1.0
B 2020-02-07 18:57:00 0.0
2020-02-07 21:50:00 1.0
2020-02-12 19:03:00 2.0
C 2020-02-01 13:50:00 0.0
2020-02-11 15:50:00 0.0
2020-02-21 10:50:00 0.0
您的示例仅跨越一周(在我们使用groupby ID之后),因此我们无法看到7天窗口是否正常工作。你能把你的例子做得更大些吗,来验证一下吗?@smci,说得对。更新了上面的OK,这就是为什么它会有那个输出。感谢您不仅提供了代码,还提供了解释。回答得很好。标记:。如果熊猫文档在您使用rolling
vsGrouper
时没有充分覆盖,那么docbug值得归档。。。