如何用Pandas向量化方法根据日期为DataFrame分配投资列值?
问题
现有两个Pandas DataFrame:
- df1(包含股票、起始日期及投资额):
Stock,StartDate,Investment A,2022-01-01,100 A,2022-02-01,150 B,2022-01-01,90 B,2022-01-15,100 ...
- df2(包含股票及日期):
Stock,Date A,2022-01-01 A,2022-01-02 A,2022-01-05 ... B,2022-01-01 ...
需要为df2添加Investment列,取值规则:对df2中股票S的日期d,匹配df1中满足d >= StartDate且d < 下一个StartDate的投资额。预期输出示例:
Stock,Date,Investment A,2022-01-01,100 A,2022-01-02,100 A,2022-01-05,100 ... A,2022-01-31,100 A,2022-02-01,150 A,2022-02-02,150 ... B,2022-01-01,90 B,2022-01-02,90 ... B,2022-01-14,90 B,2022-01-15,100 B,2022-01-16,100 ...
循环方法可实现需求,但需要更高效的向量化方案,求最优实现方式?
最优向量化实现方案
可以通过分组排序+时间区间映射的方式实现,全程用Pandas内置向量化操作,避免循环,效率最优:
- 预处理日期格式:确保两个DataFrame的日期列转为
datetime类型,避免字符串匹配错误:
import pandas as pd df1['StartDate'] = pd.to_datetime(df1['StartDate']) df2['Date'] = pd.to_datetime(df2['Date'])
- 排序对齐数据:对两个DataFrame按股票+日期排序,为后续匹配做准备:
df1_sorted = df1.sort_values(['Stock', 'StartDate']) df2_sorted = df2.sort_values(['Stock', 'Date'])
- 核心匹配操作:使用
merge_asof按股票分组,为df2的每个日期匹配最近的、不大于该日期的起始日期对应的投资额:
result = pd.merge_asof( df2_sorted, df1_sorted[['Stock', 'StartDate', 'Investment']], by='Stock', left_on='Date', right_on='StartDate', direction='backward' )
merge_asof是Pandas专为组内时间区间匹配设计的高效函数,底层用C实现,会自动为同一只股票的每个日期找到符合d >= StartDate且d < 下一个StartDate的投资额。
- 整理输出结果:移除多余列,调整列顺序:
result = result.drop('StartDate', axis=1)[['Stock', 'Date', 'Investment']]
方案优势
- 全程无显式循环,所有操作都是Pandas批量处理,处理十万级以上数据时,效率比循环高数十倍;
- 逻辑简洁直观,代码易维护;
merge_asof天生适配这类“区间归属”的时间匹配场景,无需手动处理边界条件。
内容的提问来源于stack exchange,提问作者riccio777
相关产品推荐
相关产品推荐

