如何不使用循环对pandas中同id的两个DataFrame应用自定义函数
优化方案
原循环实现存在冗余执行问题:如果
df1的id列有重复值,同一个id会被多次处理,既浪费性能也可能导致结果重复,以下两种优化方案均会先对id去重后处理,从逻辑上解决该问题。
方案1:矢量化实现(性能最优,完全避免循环)
该方案用pandas内置矢量化操作实现,性能比原循环高1~2个数量级,尤其适合大数据量场景:
import pandas as pd # 步骤1:计算df1中每个id分组的常数列(全组值相同的列)取值 def get_group_constants(group): constant_cols = group.eq(group.iloc[0]).all() return group.loc[:, constant_cols].iloc[0] # 生成每个id对应的常量映射表 const_df = df1.groupby('id', as_index=False).apply(get_group_constants).reset_index(drop=True) # 步骤2:拼接两个DataFrame后关联常量值 combined = pd.concat([df1, df2], ignore_index=True) df3 = combined.merge(const_df, on='id', how='left', suffixes=('', '_override')) # 用常量值覆盖原有同名列,清除临时字段 for col in const_df.columns.drop('id'): df3[col] = df3[f"{col}_override"] df3.drop(f"{col}_override", axis=1, inplace=True)
方案2:分组apply实现(逻辑贴近原写法,可读性高)
如果希望和你原有自定义函数的逻辑保持一致,可直接用groupby的apply方法替代显式循环:
# 预分组df2,避免每次查询都遍历全表 df2_groups = dict(tuple(df2.groupby('id'))) def process_group(df1_group): group_id = df1_group.name # 兼容df2不存在对应id的情况,返回空结构避免报错 df2_group = df2_groups.get(group_id, pd.DataFrame(columns=df2.columns)) return findConstant(df1_group, df2_group) df3 = df1.groupby('id', group_keys=False).apply(process_group).reset_index(drop=True)
内容的提问来源于stack exchange,提问作者emax
相关产品推荐
相关产品推荐

