如何为股票DataFrame按Ticker匹配另一DataFrame的最近日期?
问题需求
现有两个以Date和Ticker为复合索引的DataFrame:
第一个DataFrame(收盘价数据)
| Date | Ticker | Close |
|---|---|---|
| 2020-03-20 | NVDA | 99 |
| 2021-01-19 | AAPL | 100 |
| 2022-01-19 | MSFT | 110 |
| 2023-01-20 | AAPL | 101 |
| 2023-01-20 | MSFT | 111 |
第二个DataFrame(额外日期数据)
| Ticker | Date | Data |
|---|---|---|
| AAPL | 2023-01-10 | data |
| AAPL | 2022-11-19 | data |
| MSFT | 2022-06-17 | data |
| MSFT | 2021-01-25 | data |
| NVDA | 2019-12-01 | data |
| NVDA | 2019-08-19 | data |
| NVDA | 2019-01-22 | data |
需要在第一个DataFrame中新增Closest_Date列,存储对应Ticker在第二个DataFrame中与当前Date最接近的日期,最终输出如下:
| Date | Ticker | Close | Closest_Date |
|---|---|---|---|
| 2020-03-20 | NVDA | 99 | 2019-12-01 |
| 2021-01-19 | AAPL | 100 | 2022-11-19 |
| 2022-01-19 | MSFT | 110 | 2022-06-17 |
| 2023-01-20 | AAPL | 101 | 2023-01-10 |
| 2023-01-20 | MSFT | 111 | 2022-06-17 |
Pythonic实现方案
避免手动循环,利用pandas的分组和向量化操作高效完成:
import pandas as pd # 构造示例数据(实际使用时替换为你的真实DataFrame) df_close = pd.DataFrame({ 'Date': ['2020-03-20', '2021-01-19', '2022-01-19', '2023-01-20', '2023-01-20'], 'Ticker': ['NVDA', 'AAPL', 'MSFT', 'AAPL', 'MSFT'], 'Close': [99, 100, 110, 101, 111] }).set_index(['Date', 'Ticker']) df_data = pd.DataFrame({ 'Ticker': ['AAPL', 'AAPL', 'MSFT', 'MSFT', 'NVDA', 'NVDA', 'NVDA'], 'Date': ['2023-01-10', '2022-11-19', '2022-06-17', '2021-01-25', '2019-12-01', '2019-08-19', '2019-01-22'], 'Data': ['data']*7 }).set_index(['Ticker', 'Date']) # 步骤1:重置索引并转换日期为datetime类型,确保日期计算准确 df_close_reset = df_close.reset_index().astype({'Date': 'datetime64[ns]'}) df_data_reset = df_data.reset_index().astype({'Date': 'datetime64[ns]'}) # 步骤2:按Ticker分组整理日期列表,避免重复查询 ticker_date_map = df_data_reset.groupby('Ticker')['Date'].apply(list).to_dict() # 步骤3:定义函数查找最接近的日期,利用argmin快速定位最小差值 def get_closest(target_date, date_list): date_series = pd.Series(date_list) return date_series.iloc[(date_series - target_date).abs().argmin()] # 步骤4:批量生成Closest_Date列 df_close_reset['Closest_Date'] = df_close_reset.apply( lambda x: get_closest(x['Date'], ticker_date_map[x['Ticker']]), axis=1 ) # 步骤5:还原为原复合索引结构 result_df = df_close_reset.set_index(['Date', 'Ticker']) print(result_df)
关键说明
- 日期类型转换:必须将
Date转为datetime64类型,才能进行合法的日期差值计算。 - 分组预存日期:通过
groupby将每个股票的日期列表存入字典,避免每次查询都遍历整个DataFrame,大幅提升效率。 - 向量化差值计算:使用
(date_series - target_date).abs().argmin()替代循环比较,利用pandas/numpy的底层优化实现高效计算。
内容的提问来源于stack exchange,提问作者cam
相关产品推荐
相关产品推荐

