基于条件DataFrame批量更新目标DataFrame值的性能优化求助
问题背景
我有一个约300行的条件DataFrame(命名为POOL):
pd.DataFrame({"PERSONALNR":["000009461","000009461"],"PERIODE":["202401","202402"],"MANDANT":["LB","LB"],"DA":["01","01"]})
其中PERSONALNR和PERIODE为匹配条件,需将MANDANT和DA的值替换到目标DataFrame(命名为LA)中。
目标DataFrame约有11万行,结构如下:
pd.DataFrame({"PERSONALNR":["000009461","000009461"],"PERIODE":["202401","202402"],"MANDANT":["LB","LB"],"DA":["01","01"], "KSTBEZ":["Springer pool","bla bla"]})
当前实现方案:
for row in POOL.itertuples(): LA.loc[(LA.PERSONALNR==row.PERSONALNR)&(LA.PERIODE==row.PERIODE)&(LA.DA=="01")&(LA.KSTBEZ.str.contains("pool")),["MANDANT","DA"]]=[row.MANDANT,row.DA]
该方案处理11万行数据耗时约10秒,但处理100万行数据时耗时长达10分钟,现寻求更高效的优化方案。
优化方案
方法一:先筛选目标子集再批量合并(推荐)
利用pandas的向量化操作替代逐行循环,先定位需要更新的行,再通过合并批量赋值:
- 筛选
LA中符合更新条件的子集:
mask = (LA["DA"] == "01") & LA["KSTBEZ"].str.contains("pool") LA_subset = LA[mask].copy()
- 和
POOL按匹配条件合并,获取新值:
merged = LA_subset.merge(POOL, on=["PERSONALNR", "PERIODE"], suffixes=("", "_new"), how="left")
- 更新子集并同步回原DataFrame:
# 用新值替换,未匹配到的保留原数据 merged["MANDANT"] = merged["MANDANT_new"].fillna(merged["MANDANT"]) merged["DA"] = merged["DA_new"].fillna(merged["DA"]) merged = merged.drop(["MANDANT_new", "DA_new"], axis=1) # 同步回原LA LA.update(merged)
方法二:构建字典映射批量更新
将POOL转换为匹配键值对的字典,直接批量映射赋值:
# 构建以(PERSONALNR, PERIODE)为键的映射字典 map_dict = POOL.set_index(["PERSONALNR", "PERIODE"])[["MANDANT", "DA"]].to_dict("index") # 生成更新掩码 mask = (LA["DA"] == "01") & LA["KSTBEZ"].str.contains("pool") # 批量赋值,未匹配到的保留原数据 LA.loc[mask, ["MANDANT", "DA"]] = ( LA.loc[mask, ["PERSONALNR", "PERIODE"]] .apply(lambda x: map_dict.get(tuple(x), (x["MANDANT"], x["DA"])), axis=1) .tolist() )
方法三:设置联合索引后直接更新
给两个DataFrame设置相同的联合索引,利用索引对齐快速更新:
# 设置联合索引 LA_indexed = LA.set_index(["PERSONALNR", "PERIODE"]) POOL_indexed = POOL.set_index(["PERSONALNR", "PERIODE"]) # 生成更新掩码 mask = (LA_indexed["DA"] == "01") & LA_indexed["KSTBEZ"].str.contains("pool") # 批量更新匹配行 LA_indexed.loc[mask, ["MANDANT", "DA"]] = POOL_indexed.loc[LA_indexed[mask].index, ["MANDANT", "DA"]] # 恢复原索引 LA = LA_indexed.reset_index()
性能说明
以上方案均采用pandas原生向量化操作,避免了逐行循环的性能损耗,百万级数据处理耗时可控制在几十秒内,远优于原循环方案。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

