Pandas DataFrame行级操作优化:高效生成Minor-1列替代循环
高效实现Pandas分组生成"Minor-1"列的方案
问题规则
需要为Pandas DataFrame生成新列"Minor-1",规则如下:
- 每个
Major分组的首行值为"Start" - 分组内后续行:
- 若当前
Minor与上一行不同,则取上一行的Minor值 - 若当前
Minor与上一行相同,则继承上一行的"Minor-1"值
- 若当前
输入数据
import pandas as pd data = {'Major' : ['A112','A112','B113','B113','B113','C114','C114','C114','C114'], 'Minor' : ['X','Y','X','Y','Z','X','Y','Y','Z']} df = pd.DataFrame(data)
高效解决方案(矢量化实现)
使用Pandas分组和矢量化操作替代循环,大幅提升处理效率:
# 计算分组内上一行的Minor值 prev_minor = df.groupby('Major')['Minor'].shift(1) # 标记每个分组的首行 is_first = df.groupby('Major').cumcount() == 0 # 标记Minor值发生变化的行 minor_changed = df['Minor'] != prev_minor # 初始化Minor-1列 df['Minor-1'] = None df.loc[is_first, 'Minor-1'] = 'Start' df.loc[~is_first & minor_changed, 'Minor-1'] = prev_minor[~is_first & minor_changed] # 分组内向前填充NaN,继承上一行的Minor-1值 df['Minor-1'] = df.groupby('Major')['Minor-1'].ffill() # 验证结果 print(df.to_dict())
输出结果
{'Major': {0: 'A112', 1: 'A112', 2: 'B113', 3: 'B113', 4: 'B113', 5: 'C114', 6: 'C114', 7: 'C114', 8: 'C114'}, 'Minor': {0: 'X', 1: 'Y', 2: 'X', 3: 'Y', 4: 'Z', 5: 'X', 6: 'Y', 7: 'Y', 8: 'Z'}, 'Minor-1': {0: 'Start', 1: 'X', 2: 'Start', 3: 'X', 4: 'Y', 5: 'Start', 6: 'X', 7: 'X', 8: 'Y'}}
方案说明
- 前置Minor计算:通过
groupby.shift(1)获取同组内上一行的Minor值,避免循环遍历。 - 首行与变化标记:用
cumcount()快速定位分组首行,通过直接对比判断Minor是否变化。 - 初始化与填充:先为符合规则的行赋值,再用
ffill()在分组内填充NaN,自动继承上一行的"Minor-1"值,完全利用Pandas的矢量化优化,效率远高于Python循环或iterrows。
内容的提问来源于stack exchange,提问作者Tihom_Rahtus
相关产品推荐
相关产品推荐

