Pandas DataFrame新增行并填充关联字段的高效方法咨询
Pandas 批量新增工序记录的向量化实现
你原来的逐零件循环方案属于典型的Pandas反模式,所有逻辑在Python解释器层逐组执行,数据量上来后性能会非常差。完全可以用内置的分组聚合向量化操作替代,全程没有显式循环,性能比循环方案高1~2个数量级,比你后来写的merge方案逻辑更简洁、冗余计算更少。
实现逻辑
核心思路是先算好每个零件号的属性值,再生成新行,避免拼接后再补空值:
- 读取原始数据后,直接按
partNo分组,批量计算每个零件对应的planRev、planStatus众数 - 基于分组统计结果直接生成
operation='000'的新记录,新记录自带正确的planRev、planStatus值,不需要后续填充 - 把原始数据中非000工序的
planStatus批量置空 - 拼接原始数据和新记录,排序后直接得到目标结果
完整实现代码
import pandas as pd import pyodbc # 数据库读取数据,统一转换为string类型 server = "" cnxn = "" query = ("") try: df = pd.read_sql(query, cnxn).astype('string') except: print("query failed") else: cnxn.close() # 按零件号分组,批量统计每个零件的计划版本、计划状态众数 part_attr = df.groupby('partNo', as_index=False).agg( planRev=('planRev', lambda x: x.value_counts().idxmax()), planStatus=('planStatus', lambda x: x.value_counts().idxmax()) ) # 生成需要新增的000工序记录 new_rows = part_attr.copy() new_rows['operation'] = '000' # 如需给cimxDatabase字段赋值,直接批量设置即可 new_rows['cimxDatabase'] = 'WLCAPP' # 原表所有非000工序的planStatus批量置空 df['planStatus'] = pd.NA # 拼接、排序得到最终结果 final_df = pd.concat([df, new_rows], ignore_index=True)\ .sort_values(by=['partNo', 'operation'])\ .reset_index(drop=True)
方案说明
- 所有操作都是Pandas向量化实现,计算逻辑在C层执行,没有Python层的显式循环,百万行级数据也能在几百毫秒内处理完成
- 避免了先拼接产生空值、再merge填充的冗余步骤,内存占用更低
- 如果存在同个零件下多个值出现次数相同并列众数的场景,
value_counts().idxmax()会默认返回值排序靠前的结果,如需调整众数选取规则,只需要修改agg中的匿名函数逻辑即可,不需要改动整体流程。
内容的提问来源于stack exchange,提问作者smichael_44
相关产品推荐
相关产品推荐

