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

如何用Pandas在指定列定义的区间内查找最小值?

Pandas大数据集下按动态区间计算列最小值的优化问题

需求说明

需要在Pandas DataFrame中,根据boo列的重复值(如1-1、2-2)定义区间,找出每个区间内foo列的最小值,并将结果新增为min列。boo列的值由前期代码动态生成,无法提前预知,因此无法预先创建比对列表。

示例DataFrame

foo           boo
15  36.377949      
16  42.489706     1
17  41.223734      
18  32.281779     0
19  22.888312     2   
20  12.847996      
21   6.876954      
22 -23.872935     1    
23 -31.858878         
24 -39.404905     3   
25 -47.724924     2
26 -4.8161051     3

期望输出

foo           boo    min
15  36.377949      
16  42.489706     1
17  41.223734      
18  32.281779     0      
19  22.888312     2   
20  12.847996      
21   6.876954      
22 -23.872935     1      -23
23 -31.858878         
24 -39.404905     3   
25 -47.724924     2      -47
26 -4.8161051     3      -47

已知基础for循环可以实现该需求,但未利用Pandas的性能优势,因此希望基于DataFrame/Pandas/Numpy实现高效解决方案。


测试与后续问题

大数据集性能瓶颈

尝试了两种推荐方法,在小数据集上可以正常运行,但面对150-250万行的大数据集时,执行时间过长甚至无法完成:

  • function1:采用Pedro Rocha的find_min_in_range方法,调整后处理完整数据集需要4-5分钟
  • function2:采用mozway的for循环方法

性能最优方案与复现问题

经过多轮测试,Pedro的Option1和Option3性能最优:

  • Option3处理1725410行、204954个区间的数据集耗时172秒,但不确定在1vCPU机器上的适用性
  • 数据集可通过read_parquet加载,区间数量通常不超过总行数的25%,且均为闭合区间(0区间除外)

但无法复现Pedro的Option2,运行时出现索引错误,错误信息如下:

File "/.../option2.py", line 96, in <lambda>
    df.loc[idx,"min"] = df.loc[idx].apply(lambda row: df.loc[range(*df[df.boo == row["boo"]].index[[0,-1]]+[0,1]),"foo"].min(), axis=1)
  File "/.../venv/lib/python3.10/site-packages/pandas/core/indexes/base.py", line 5069, in __getitem__
    result = getitem(key)
IndexError: index 0 is out of bounds for axis 0 with size 0

考虑关闭此问题,重新创建聚焦性能优化的新问题。

基准测试方法

分享用于测试的基准方法:使用简化版测试数据集(约20万个区间),通过timeit测量执行时间,将结果整理为表格并生成图表。代码示例如下:

from timeit import default_timer as timer
import pandas as pd
import numpy as np

# 省略数据加载步骤,可通过read_parquet读取示例文件模拟

times = []
for i in range(10000, 210000, 10000):
  df = input_df[:i].copy()
  start = timer()
  # 此处填入待测试的解决方案代码
  ...
  elapsed_time = round(timer() - start, 1)
  times.append({'rows': i, 'time': elapsed_time})

# 输出执行时间
for t in times:
  print(f"行数: {t['rows']}, 耗时: {t['time']}秒")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 16:01:00