如何高效在百万级Pandas DataFrame中计算自定义最小值字段?
高效实现Pandas DataFrame的minimum字段计算
数据准备
创建目标DataFrame:
import pandas as pd import numpy as np ds = { 'trend' : [1,1,1,1,2,2,3,3,3,3,3,3,4,4,4,4,4], 'price' : [23,43,56,21,43,55,54,32,9,12,11,12,23,3,2,1,1]} df = pd.DataFrame(data=ds)
DataFrame结构:
trend price 0 1 23 1 1 43 2 1 56 3 1 21 4 2 43 5 2 55 6 3 54 7 3 32 8 3 9 9 3 12 10 3 11 11 3 12 12 4 23 13 4 3 14 4 2 15 4 1 16 4 1
保存为本地文件:
df.to_csv("df.csv", index = False)
需求说明
需要新增minimum字段,规则为:对每一条记录,取当前记录的price值,与截至当前记录时所有已出现trend的最后一个price值的最小值。
示例对应结果:
- 第0条:仅trend1的最后price为23,
min(23,23)=23 - 第4条:已出现trend1(最后price21)和trend2(当前price43),
min(43,21)=21 - 第14条:已出现trend1、2、3(最后price12)和trend4(当前price2),
min(2,12)=2
低效实现问题
以下代码逻辑正确,但每次循环都重新读取文件、分组聚合,时间复杂度为O(n²),处理百万级数据时效率极低:
minimum = [] for i in range(len(df)): ds = pd.read_csv("df.csv", nrows=i+1) d = ds.groupby('trend', as_index=False).agg({'price':'last'}) d['minimum'] = d['price'].min() minimum.append(d['minimum'].iloc[-1]) ds['minimum'] = minimum
运行后目标结果:
trend price minimum 0 1 23 23 1 1 43 43 2 1 56 56 3 1 21 21 4 2 43 21 5 2 55 21 6 3 54 21 7 3 32 21 8 3 9 9 9 3 12 12 10 3 11 11 11 3 12 12 12 4 23 12 13 4 3 3 14 4 2 2 15 4 1 1 16 4 1 1
高效解决方案
通过维护字典记录每个trend的最新price,实时跟踪全局最小值,将时间复杂度降至O(n),仅在必要时重新计算全局最小值,大幅提升效率:
# 保存每个trend的最新price trend_latest = {} # 当前所有trend最新price的最小值 current_global_min = float('inf') minimum_list = [] for _, row in df.iterrows(): trend = row['trend'] current_price = row['price'] old_price = trend_latest.get(trend) # 更新当前trend的最新price trend_latest[trend] = current_price if old_price is None: # 新增trend,更新全局最小值 current_global_min = min(current_global_min, current_price) else: # 已有trend更新价格,仅在原价格是全局最小值时重新计算全局最小值 if old_price == current_global_min: current_global_min = min(trend_latest.values()) else: # 否则仅比较当前价格与全局最小值 current_global_min = min(current_global_min, current_price) # 计算当前行的minimum current_min = min(current_price, current_global_min) minimum_list.append(current_min) df['minimum'] = minimum_list print(df)
该代码运行结果与目标一致,处理百万级数据时可在数秒内完成。
内容的提问来源于stack exchange,提问作者Giampaolo Levorato
相关产品推荐
相关产品推荐

