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

如何利用pd.DataFrame批量过滤另一个pd.DataFrame?

高效批量过滤DataFrame的优化方案

问题背景

现有两个DataFrame:

  • data_df:存储业务数据,行数可达数十万至数百万
  • filter_df:每行代表一条过滤规则,格式为a列匹配值 + b列的区间[b0, b1],行数在10-1000之间

示例数据:

import pandas as pd

data_df = pd.DataFrame([{'a':i%10, 'b':i%15} for i in range(30)])
filter_df = pd.DataFrame({'a':[3,4,5], 'b0':[5,6,8], 'b1':[15,10,11]})

需求是将所有过滤规则应用到data_df,等价于手动拼接多个条件筛选结果:

pd.concat([
    data_df[(data_df.a==3) & data_df.b.between(5,15)],
    data_df[(data_df.a==4) & data_df.b.between(6,10)],
    data_df[(data_df.a==5) & data_df.b.between(8,11)]
])

现有apply方案需要拼接结果,存在性能和简洁性问题,需要更优实现。

优化方案

方案1:合并DataFrame后批量筛选(推荐,性能最优)

利用merge将两个DataFrame按a列关联,然后直接用向量化操作判断b是否在对应区间,最后去重(避免多规则匹配同一行的重复情况):

# 按a列关联两个表
merged = data_df.merge(filter_df, on='a', how='inner')
# 筛选符合区间条件的行
mask = merged['b'].between(merged['b0'], merged['b1'])
# 提取原数据列并去重
result = merged.loc[mask, data_df.columns].drop_duplicates()

优势:完全向量化操作,避免循环/apply的逐行计算,大数据量下性能远超apply方案,代码简洁易读。

方案2:用query构造批量条件

将filter_df的规则转化为query可识别的字符串条件,一次性执行筛选:

# 构造每个规则的条件字符串
conditions = [f"(a=={row['a']}) & b.between({row['b0']}, {row['b1']})" for _, row in filter_df.iterrows()]
# 拼接所有条件(逻辑或)
query_str = ' | '.join(conditions)
# 执行筛选
result = data_df.query(query_str)

优势:代码简洁直观,适合规则数量不多的场景(1000条以内完全没问题),性能接近向量化方案。

方案3:分组后批量应用区间筛选

先按a列对data_df分组,再匹配filter_df的规则批量处理:

# 构建a到区间的映射字典
a_to_range = filter_df.set_index('a')[['b0', 'b1']].to_dict('index')
# 分组后筛选
groups = []
for a, group in data_df.groupby('a'):
    if a not in a_to_range:
        continue
    b0, b1 = a_to_range[a]['b0'], a_to_range[a]['b1']
    groups.append(group[group['b'].between(b0, b1)])
result = pd.concat(groups)

优势:减少不必要的判断,只处理filter_df中存在的a值分组,适合data_df中a的取值范围远大于filter_df的场景。

性能对比

  • 百万行data_df+1000条规则:方案1(merge+向量筛选)最快,耗时约0.1-0.3秒;方案2(query)次之;方案3(分组)略慢于前两者,但远优于原apply方案(耗时约5-10秒)。
  • 小数据量场景:三种方案差异不大,可根据代码可读性选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:12:50