Python Pandas:如何实现同ID行计数递增,不同则置1?
解决Pandas中分组连续计数的问题
问题背景
原始已排序DataFrame:
Id A A B C D D D D E
需求:新增value列,规则为:
- 当前行
Id与上一行不同时,赋值为1 - 当前行
Id与上一行相同时,赋值为上一行value值加1
你的尝试与错误
你通过shift()创建了Previous_id列:
df['Previous_id'] = df['Id'].shift(1)
得到的DataFrame:
Id Previous_id A NaN A A B A C B D C D D D D D D E D
但使用自定义函数apply时出现错误:
def func1(row): if row['Id'] != row['Previous_id']: return 1 else: return row['value'].shift(1) + 1 df['value'] = df.apply(lambda row: func1(row), axis=1)
错误信息:
'int' object has no attribute 'shift'
错误原因:行级apply中,row['value']是单个数值(不是Series),无法调用shift();而且此时value列还未创建,根本取不到上一行的value值。
正确解决方法
方法一:向量化分组计数(推荐,高效简洁)
不需要创建Previous_id列,直接利用Pandas的分组和累计计数功能:
# 生成分组键:每次Id变化时分组键+1 df['value'] = df.groupby((df['Id'] != df['Id'].shift(1)).cumsum()).cumcount() + 1
分步拆解更直观:
# 1. 标记每个连续分组的起始点,生成分组键 df['group_key'] = (df['Id'] != df['Id'].shift(1)).cumsum() # 2. 每个分组内从1开始累计计数 df['value'] = df.groupby('group_key').cumcount() + 1 # 3. 不需要group_key可删除 df = df.drop('group_key', axis=1)
方法二:迭代行处理(适合理解逻辑,小数据量可用)
通过迭代每一行,维护上一个Id和当前计数的变量:
prev_id = None current_value = 1 values_list = [] for _, row in df.iterrows(): if row['Id'] != prev_id: current_value = 1 else: current_value += 1 values_list.append(current_value) prev_id = row['Id'] df['value'] = values_list
最终结果
执行后得到期望的DataFrame:
Id Previous_id value A NaN 1 A A 2 B A 1 C B 1 D C 1 D D 2 D D 3 D D 4 E D 1
内容的提问来源于stack exchange,提问作者zukowski2012
相关产品推荐
相关产品推荐

