如何用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_
相关产品推荐
相关产品推荐

