过去几个小时一直试图解决这个问题而没有运气。
我有一个数据帧如下:
id = [1,1,1,2,2,2]
weeks = [1,2,3,1,2,3]
contr = [16,16,22,37,37,16]
df = pd.DataFrame({'ID' : id,
'Week' : weeks,
'Contract' : contr})
print(df)
ID Week Contract
0 1 1 16
1 1 2 16
2 1 3 22
3 2 1 37
4 2 2 37
5 2 3 16
现在我要做的是在给定的一周内按ID计算合同的更改数量(我的df很小,大约180万行)
所以我认为可以工作的是对一个值的滚动计数,该值不等于上面我通过玩这个代码尝试过的值:
df['count'] = df['ID'].groupby((df['Contract'] != df['Contract'].shift(-1)).cumsum()).cumcount()
但这并没有给我预期的结果,
我所追求的是以下内容
print(df)
ID Week Contract count
0 1 1 16 0 # First instance is this is ignored
1 1 2 16 0 # No Change so 0
2 1 3 22 1 # Change here so 1
3 2 1 37 0
4 2 2 37 0
5 2 3 16 1
6 2 4 16 0 # This should be 0 as the change was in the prev Week
(如果这不符合一个小问题,请告诉我)。
我认为使用diff
来获得价值变化,然后我们需要groupby
的另一个cumsum
到ID
s=df.groupby('ID').Contract.diff().ne(0)
s.groupby(df['ID']).cumsum()-1
Out[33]:
0 0.0
1 0.0
2 1.0
3 0.0
4 0.0
5 1.0
Name: Contract, dtype: float64
df['Count']=s.groupby(df['ID']).cumsum()-1
使用申请:
df['Count']=df.groupby('ID')['Contract'].apply(lambda x: (~x.duplicated()).cumsum()-1)
#or df.groupby('ID')['Contract'].transform(lambda x: pd.factorize(x)[0])
print(df)
ID Week Contract Count
0 1 1 16 0
1 1 2 16 0
2 1 3 22 1
3 2 1 37 0
4 2 2 37 0
5 2 3 16 1