Pandas数据框中为满足条件的连续行生成递增序号的最优方法
Pandas逐行连续计数的最优实现
这类生成连续序号的需求,完全不需要写Python层面的逐行循环,向量化实现的性能比逐行.loc索引的写法高2~3个数量级,也能避免新手写循环时常见的逻辑bug。
你当前的循环写法存在两个硬伤:
- 循环每跑完一行就把计数变量j重置为2,根本没法生成连续递增的数值
- 逐行调用
.loc读写单元格的写法,数据量超过1万行时运行效率会暴跌
匹配你业务场景的实现步骤
你的核心需求是:针对连续满足判定条件的行块,在块内部生成1、2、3…的连续整数序列,非满足条件的行该列留空,最终生成的序列可以直接用于透视表,且能配合第二个索引字段实现正确分组。
第一步:生成判定布尔掩码
先把“是否Duplicate为TRUE”的判断逻辑生成布尔Series,这是所有操作的基础:
# 新手常踩的坑:如果Duplicate列本身存的是布尔值,判断时不要给TRUE加引号,否则判断会恒为False is_target_row = sales_data_cleansed_2['Duplicate'] == 'TRUE'
第二步:识别连续行块的边界
不需要手动遍历找连续行,通过布尔值的变化即可标记出所有连续同状态的行块:
# 当前行和上一行的判定结果不一致时,累计计数加1,给每个连续块分配唯一编号 block_id = (is_target_row != is_target_row.shift(1)).cumsum()
第三步:块内生成连续递增序号
# 每个块内部按行顺序累计位置,加1后即为从1开始的连续序号;不满足条件的行自动赋值为空值 sales_data_cleansed_2['sales_index'] = is_target_row.groupby(block_id).cumcount() + 1
常见需求错配说明
根据后续做透视表的使用场景,要先确认自己需要的是哪种计数逻辑,避免用错了序号导致透视结果错位:
- 上面的默认实现是块内独立计数:比如数据里有3段连续满足条件的行,每一段内部的序号都是从1开始重新累加,这种方式生成的序号作为块内标记,配合第二个分组字段做透视时,不会出现不同块的序号冲突的问题,完全匹配你的业务场景
- 如果需要的是全局顺序计数:也就是不管满足条件的行是不是连续出现,只要是满足条件的行,就按行出现的先后顺序,全局累加生成1、2、3…n的连续序列,那只需要一行代码实现:
sales_data_cleansed_2.loc[is_target_row, 'sales_index'] = range(1, is_target_row.sum() + 1)
内容的提问来源于stack exchange,提问作者Matt C
相关产品推荐
相关产品推荐

