如何按ID分组统计Pandas DataFrame中CD字段的变化次数?
解决按ID统计CD字段变化次数的问题
cumcount()是用来给组内元素生成连续编号的方法,无法直接统计字段值的变化次数。我们可以通过相邻值比较+分组聚合的方式实现需求,分两种常见场景说明:
场景1:统计每个ID的CD总变化次数
实现步骤
- 按
ID分组,用shift()获取每组内CD列的上一行值 - 对比当前行与上一行的
CD值,标记是否发生变化(变化时为True) - 对每组的变化标记求和,得到该ID的总变化次数
代码实现
import pandas as pd df = pd.DataFrame({ 'ID': [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], 'DATE': ['1/1/2015','1/2/2015', '1/3/2015','1/4/2015','1/5/2015','1/6/2015','1/7/2015','1/8/2015', '1/9/2016','1/2/2015','1/3/2015','1/4/2015','1/5/2015','1/6/2015','1/7/2015'], 'CD': ['A','A','A','A','B','B','A','A','C','A','A','A','A','A','A']}) # 标记CD是否发生变化 df['cd_changed'] = df.groupby('ID')['CD'].apply(lambda x: x != x.shift()) # 按ID统计总变化次数 change_counts = df.groupby('ID')['cd_changed'].sum().astype(int) print(change_counts)
输出结果
ID 1 3 2 0 Name: cd_changed, dtype: int64
解释:ID1的CD经历了A→B、B→A、A→C三次变化;ID2的CD始终为A,无变化。
场景2:生成每行的累计变化次数(到当前行为止的变化次数)
如果需要在原数据中添加一列,记录每行所属ID到当前行的累计变化次数,可以对分组后的变化标记做累加:
代码实现
df['cumulative_changes'] = df.groupby('ID')['cd_changed'].cumsum().astype(int) print(df[['ID', 'CD', 'cumulative_changes']])
输出结果
ID CD cumulative_changes 0 1 A 0 1 1 A 0 2 1 A 0 3 1 A 0 4 1 B 1 5 1 B 1 6 1 A 2 7 1 A 2 8 1 C 3 9 2 A 0 10 2 A 0 11 2 A 0 12 2 A 0 13 2 A 0 14 2 A 0
关键说明
shift()方法会获取组内上一行的CD值,每组第一行的shift()结果为NaN,与当前值比较时返回False,不会影响统计结果- 布尔值求和时,
True会被视为1,False视为0,直接求和即可得到变化次数
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

