pandas不逐行遍历创建多层级运行总计列的最优实现方法
Pandas 无逐行遍历实现连续值分层运行总计的最佳方案
全程使用pandas原生向量化运算,无任何逐行循环、无自定义逐行apply,完全符合pandastic设计规范,性能可支撑百万级以上数据量快速计算。
核心逻辑
连续相同值序列的识别核心是定位「值发生跳变」的分界点:
- 先标记所有值为
X的行 - 识别每一段连续
X的起始行(当前行是X、上一行不是X) - 基于起始行标记做累计求和生成全局序列编号,再按全局编号分组生成组内位置序号
- 最后将非
X行的结果统一置为空值即可
完整实现代码
import pandas as pd import numpy as np # 构造示例输入数据 df = pd.DataFrame() df['test'] = np.nan,np.nan,'X','X','X','X',np.nan,'X','X','X','X','X','X',np.nan,np.nan,'X','X' # 核心计算逻辑 is_x_mask = df['test'].eq('X') # 标记每个连续X块的起始位置 new_block_flag = is_x_mask & (~is_x_mask.shift(fill_value=False)) # 生成连续X块的全局递增编号 block_id_col = new_block_flag.cumsum() # 生成每个X在所属块内的递增序号 inner_pos_col = block_id_col.groupby(block_id_col).cumcount() + 1 # 非X位置赋值为空值,使用pandas推荐的可空整数类型存储 df['desired_output_level_1'] = block_id_col.where(is_x_mask, np.nan).astype('Int64') df['desired_output_level_2'] = inner_pos_col.where(is_x_mask, np.nan).astype('Int64')
结果验证
运行上述代码后输出结果与需求完全匹配:
test desired_output_level_1 desired_output_level_2 0 NaN <NA> <NA> 1 NaN <NA> <NA> 2 X 1 1 3 X 1 2 4 X 1 3 5 X 1 4 6 NaN <NA> <NA> 7 X 2 1 8 X 2 2 9 X 2 3 10 X 2 4 11 X 2 5 12 X 2 6 13 NaN <NA> <NA> 14 NaN <NA> <NA> 15 X 3 1 16 X 3 2
注:如果需要和示例一样用字符串格式存储编号,只要在最后赋值时追加
.astype(str)即可,实际做数值统计时推荐用可空整数类型,性能和计算兼容性更好。
内容的提问来源于stack exchange,提问作者bud fox
相关产品推荐
相关产品推荐

