Pandas按uid分组、按date排序提取最早日期对应price的矢量化实现
优化Pandas分组提取最早日期对应价格的代码
问题背景
现有df_prices DataFrame,包含uid(存在重复值)、date、price三列,数据示例:
df_prices index uid date price 0 123 02-02-2000 11100 1 123 01-01-2000 22200 2 123 03-03-2000 44000 3 123 04-04-2000 66000 4 456 03-03-2000 77700 5 456 02-02-2000 88800 6 456 04-04-2000 66600 ... ... ... ... 98 987 01-01-2005 12300 99 987 04-04-2005 45600 100 987 05-05-2005 78900
需求:按uid分组,每组按date排序后提取最早日期对应的price,生成包含唯一uid和对应最早价格的df_oldest_prices DataFrame,结果示例:
df_oldest_prices index uid price 0 123 22200 1 456 88800 ... ... ... 40 987 12300
此前通过iterrows循环实现,效率偏低,需要用矢量化Pandas代码优化,且不能使用pivot方法。
优化方案
步骤1:统一日期格式(关键)
首先将date列转换为datetime类型,避免字符串排序导致的逻辑错误:
import pandas as pd df_prices['date'] = pd.to_datetime(df_prices['date'], format='%d-%m-%Y')
步骤2:矢量化提取目标数据
提供两种高效实现方式:
方式一:分组取首行
先按uid和date升序排序,再分组提取每组第一行:
df_oldest_prices = df_prices.sort_values(['uid', 'date']) \ .groupby('uid', as_index=False) \ .first()[['uid', 'price']]
方式二:去重保留首行(性能更优)
排序后直接对uid去重,保留每组最早的行:
df_oldest_prices = df_prices.sort_values(['uid', 'date']) \ .drop_duplicates(subset='uid', keep='first') \ .reset_index(drop=True)[['uid', 'price']]
说明
- 转换日期类型是核心前提,否则字符串格式的日期会按字符顺序排序,跨年份场景下会出现结果错误。
- 两种方式均为矢量化操作,相比
iterrows循环效率提升显著,其中drop_duplicates的方式在数据量较大时性能更优,因为避免了分组操作的额外开销。
内容的提问来源于stack exchange,提问作者Fabio
相关产品推荐
相关产品推荐

