如何计算每个(thing,cond = any)事件之前发生的多列(thing,cond = 1)事件的发生次数? / strong>
(这些可能是按玩家赢得扑克游戏,因患者而沮丧的情节,等等。)例如,下面的第index == 3
行包含(thing, cond) = (c,2)
对,并显示数字以前的 (c,1)
发生次数,在priors
列中正确(但手动)显示为0
。我有兴趣生成一个合成列,其中包含我数据中每个(thing,event)对的先前(thing,1)事件的计数。我的数据随着时间单调增加。如果有帮助,silly
DataFrame
中的自然索引可以视为逻辑刻度。 (<旁白>:确实不是。)
为方便起见,下面是我的测试DataFrame
和手动生成的priors
列的代码,无论groupby
,{ {1}},cumsum
,shift
等。我尝试。我用谷歌搜索和破坏了我的大脑好几天了。似乎没有合适的答案。读取“先验”列的关键是它的条目必须说:“在此(a,1)或(a,2)事件之前,已经有2(a,1)个事件。”
where
我最近来的是:
[In]:
import pandas as pd
silly = pd.DataFrame({'thing': ['a','b','a','c','b','c','c','a','a','b','c','a'], "cond": [1,2,1,2,1,2,1,2,1,2,1,2]})
silly['priors'] = pd.Series([0,0,1,0,0,0,0,2,2,1,1,3])
silly
[Out]:
silly
thing cond priors
0 a 1 0
1 b 2 0
2 a 1 1
3 c 2 0
4 b 1 0
5 c 2 0
6 c 1 0
7 a 2 2
8 a 1 2
9 b 2 1
10 c 1 1
11 a 2 3
请注意,不完整的先验列中存在的值是正确的,但并非所有所需的数据都在其中。
请尽可能保留任何“ Pythonic”答案。尽管与大多数ML问题相比,我的真实数据很小,但我想以正确的方式学习熊猫,而不是我已经看过太多的使用Python循环或itertools chicanery的玩具数据方式。先感谢您! (为此我深表歉意!)
答案 0 :(得分:2)
您需要
shift
的1。您可以使用groupby
,cumsum
和shift
进行此操作:
(df.cond.eq(1)
.groupby(df.thing)
.apply(lambda x: x.cumsum().shift())
.fillna(0, downcast='infer'))
0 0
1 0
2 1
3 0
4 0
5 0
6 0
7 2
8 2
9 1
10 1
11 3
Name: cond, dtype: int64
避免apply
的另一种方法是将两个groupby
调用链接在一起-一个进行移位,另一个进行累加。
(df.cond.eq(1)
.groupby(df.thing)
.cumsum()
.groupby(df.thing)
.shift()
.fillna(0, downcast='infer'))
0 0
1 0
2 1
3 0
4 0
5 0
6 0
7 2
8 2
9 1
10 1
11 3
Name: cond, dtype: int64