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

寻求Pandas两个DataFrame的更高效条件合并实现方法

优化DataFrame条件合并的实现方式

问题背景

我尝试编写最简示例代码实现两个DataFrame的条件合并,基于指定条件匹配对应行,目前需通过双重循环实现。示例代码如下:

import pandas as pd

df1 = pd.DataFrame([
    ['a', 'Test1', 2995],
    ['b', 'Test2', 3995],
    ['c', 'Test3', 5000]],
    columns=['ID', 'Name', 'Value'])
df2 = pd.DataFrame([
    ['1', 1, 2],
    ['2', 3, 4],
    ['3', 99, 100]],
    columns=['ID', 'Start', 'Context'])

df_test = pd.DataFrame(columns=['ID', 'Name', 'Value','Start'])
i = 0
for index, row1 in df1.iterrows():
    for index, row2 in df2.iterrows():
        if row1['Value'] + 25 > row2['Start'] * 1000 and row1['Value'] < row2['Start'] * 1000:
            df_test.loc[i] = row1
            df_test.loc[i]['Start'] = row2['Start']
        i += 1

运行后得到结果:

ID Name  Value Start
0    a  Test1  2995     3

请问是否存在更优的实现方式?


优化方案

双重循环(尤其是iterrows())的效率极低,当数据量较大时会严重拖慢运行速度。下面推荐两种基于向量化操作的高效实现方式,利用pandas/numpy的底层优化大幅提升性能:

方案1:交叉连接后过滤条件

通过merge(how='cross')生成两个DataFrame的所有行组合,再用布尔索引筛选符合条件的行,最后保留需要的列:

import pandas as pd

df1 = pd.DataFrame([
    ['a', 'Test1', 2995],
    ['b', 'Test2', 3995],
    ['c', 'Test3', 5000]],
    columns=['ID', 'Name', 'Value'])
df2 = pd.DataFrame([
    ['1', 1, 2],
    ['2', 3, 4],
    ['3', 99, 100]],
    columns=['ID', 'Start', 'Context'])

# 交叉连接,重命名重复列名避免冲突
df_cross = df1.merge(df2, how='cross', suffixes=('_df1', '_df2'))
# 应用过滤条件
condition = (df_cross['Value'] + 25 > df_cross['Start'] * 1000) & (df_cross['Value'] < df_cross['Start'] * 1000)
# 筛选结果并调整列名
df_result = df_cross.loc[condition, ['ID_df1', 'Name', 'Value', 'Start']].rename(columns={'ID_df1': 'ID'})

print(df_result)

方案2:广播机制匹配条件

利用numpy的广播特性,直接计算所有行的匹配条件,再提取符合条件的行进行合并:

import pandas as pd
import numpy as np

df1 = pd.DataFrame([
    ['a', 'Test1', 2995],
    ['b', 'Test2', 3995],
    ['c', 'Test3', 5000]],
    columns=['ID', 'Name', 'Value'])
df2 = pd.DataFrame([
    ['1', 1, 2],
    ['2', 3, 4],
    ['3', 99, 100]],
    columns=['ID', 'Start', 'Context'])

# 将数据转换为可广播的形状
values = df1['Value'].values[:, np.newaxis]
starts = df2['Start'].values * 1000

# 生成条件匹配矩阵
mask = (values + 25 > starts) & (values < starts)
# 获取所有匹配的行索引
df1_idx, df2_idx = np.where(mask)

# 合并匹配的行数据
df_result = df1.loc[df1_idx].copy()
df_result['Start'] = df2.loc[df2_idx, 'Start'].values

print(df_result)

方案优势

  • 效率提升显著:向量化操作避免了逐行循环的开销,数据量越大,性能优势越明显。
  • 代码简洁易维护:逻辑清晰,修改条件或扩展功能更方便。
  • 原生支持:完全基于pandas/numpy的原生API,无需额外依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:45:23