我有一个这样的熊猫数据框:
id some_value
0 tag1 v1
1 tag1 v2
2 tag1 v1
3 tag2 v2
4 tag2 v2
5 tag2 v3
我想知道每个IDsome_value
更改值的频率。因此,tag1
这将是两次(因为它先从v1
变为v2
然后再返回),因为tag2
它将是一次。我已经解决了这样的问题:
import pandas as pd
df = pd.DataFrame({'id': ['tag1', 'tag1', 'tag1', 'tag2', 'tag2','tag2'], 'some_value': ['v1','v2','v1','v2','v2','v3']})
mask = df['id'] == df['id'].shift(-1)
df['changed'] = df['some_value'] != df['some_value'].shift(-1)
df[mask].groupby('id').sum()
该代码可以正常工作,因为它返回
changed
id
tag1 2.0
tag2 1.0
有没有更优雅的解决方案?
实现此目的的一种方法是:
def numChanges(x):
return sum(x.iloc[:-1] != x.shift(-1).iloc[:-1])
df.groupby('id').agg({
'some_value' : numChanges
})
请注意,如果id列未排序,结果将有所不同,因此,除非您打算这样做,否则您的解决方案可能会产生不正确的结果。
例如,在我的解决方案中,下面的数据集将产生tag2值为5,但根据您的结果为3。从技术上讲,正确答案是5,但是如果对id变量进行排序,则不会有任何区别。
pd.concat([df]*3) #My solution outputs 5 changes for tag2 and yours will give 3 only
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句