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

基于DataFrame阈值为另一DataFrame高效打标签的实现方案

高效实现Pandas DataFrame按分类区间打标签(1000万行数据优化)

方案一:适用于每个分类对应唯一区间的场景

这是最高效的场景,完全通过矢量化操作替代逐行循环:

import pandas as pd

# 先确保df1的分类键唯一(避免多对多合并产生冗余数据)
df1 = df1.drop_duplicates(subset=['Category A', 'Category B'])

# 仅合并必要字段:分类、区间阈值、标签
merged = df2.merge(
    df1[['Category A', 'Category B', 'Lower Bound', 'Upper Bound', 'Label']],
    on=['Category A', 'Category B'],
    how='left'
)

# 矢量化判断Value是否在区间内,提取对应Label(可通过inclusive参数调整区间开闭)
df2['Label'] = merged['Label'].where(
    merged['Value'].between(merged['Lower Bound'], merged['Upper Bound'], inclusive='both')
)

效率优势

  • 彻底规避apply/iterrows的Python级逐行循环,全部用Pandas底层C实现的矢量化操作
  • 合并采用优化后的哈希连接,比循环匹配效率高几个数量级

方案二:适用于单个分类对应多个区间的场景

如果同一个(Category A, Category B)存在多个阈值区间,可通过合并+筛选实现:

# 合并所有分类-区间组合
merged = df2.merge(
    df1[['Category A', 'Category B', 'Lower Bound', 'Upper Bound', 'Label']],
    on=['Category A', 'Category B'],
    how='left'
)

# 筛选符合区间条件的记录
mask = merged['Value'].between(merged['Lower Bound'], merged['Upper Bound'], inclusive='both')
matched_labels = merged[mask][['id', 'Label']]

# 将匹配标签映射回原df2
df2 = df2.merge(matched_labels, on='id', how='left')

可选优化

如果区间存在重叠,可给df1添加优先级列,筛选时按优先级排序后取第一条匹配结果。


为什么你之前的merge没提速?

大概率是以下问题导致:

  1. df1存在重复分类键:合并后产生大量冗余行,拖慢后续操作,先执行df1.drop_duplicates(subset=['Category A', 'Category B'])去重
  2. 合并了不必要的列:比如df1的id列,增加内存占用和合并时间,只保留需要的字段即可
  3. 未用矢量化判断:合并后仍用循环筛选,浪费了merge的性能优势

性能参考

针对1000万行df2 + 1万条分类规则的df1:

  • 原apply+iterrows方法:预计耗时数十分钟
  • 方案一:预计耗时10-30秒(取决于硬件配置)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:37:35