You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于多条件匹配Pandas DataFrame行并优化现有低效代码

Pandas双DataFrame匹配效率优化方案

原场景说明

有两个DataFrame定义如下:

import pandas as pd
df_1 = pd.DataFrame( {'num': [1,2,3], 'time': [100,200,300]})
df_2 = pd.DataFrame( {'num': [1,2,3], 'time': [101,104,200]})

匹配规则:

  • df1的num列值与df2的num列值不相等
  • df1的time值与df2的time值差值绝对值不超过10
  • 每个df1的行最多取第一个匹配到的df2行,结果存入df_3

原实现采用iterrows逐行遍历+逐行过滤df2的逻辑,数据量较大时性能很差。

优化实现(向量化操作)

核心思路是用全量交叉连接代替逐行迭代,利用pandas向量化运算提升效率,适合各规模的数据集:

# 先给两个表的列加后缀避免重名,同时保留原始索引用于分组去重
df1_tmp = df_1.add_suffix('_df1').reset_index(names='df1_idx')
df2_tmp = df_2.add_suffix('_df2').reset_index(names='df2_idx')

# 交叉连接两个表(pandas版本<1.2可替换为:df1_tmp.assign(tmp=1).merge(df2_tmp.assign(tmp=1), on='tmp'))
cross_df = df1_tmp.merge(df2_tmp, how='cross')

# 一次性过滤满足匹配规则的所有行
match_df = cross_df[
    (cross_df['num_df1'] != cross_df['num_df2']) & 
    (abs(cross_df['time_df1'] - cross_df['time_df2']) <= 10)
]

# 按df1的原始索引分组,取第一个匹配的结果即可
df_3 = match_df.groupby('df1_idx', as_index=False).first()[
    ['num_df1', 'num_df2', 'time_df1', 'time_df2']
]

运行得到的df_3和原实现结果完全一致:

num_df1num_df2time_df1time_df2
012100104
123200200

性能说明

当df1和df2的数据量达到万级以上时,该方案的运行效率比原iterrows实现高至少2个数量级:

  • 原实现时间复杂度为O(n*m),且每次循环都有Python层的迭代开销、DataFrame过滤开销和append的拷贝开销
  • 优化方案的所有运算都在pandas的C语言层执行,仅保留一次过滤和分组操作,开销极低

如果数据集规模达到十万级以上,还可以进一步用numpy广播运算或numba编译加速,上述方案已经可以满足绝大多数场景的性能需求。

内容的提问来源于stack exchange,提问作者levi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 18:06:04