基于两个DataFrame计算IPO日期前6个月10年期美债收益率均值
解决方法
要实现为每个ipodate计算对应前6个月的国债收益率均值,核心是先统一日期格式,再用高效的时间区间匹配方法替代不适用的rolling(),具体步骤如下:
步骤1:标准化日期格式
两个DataFrame的日期格式不统一(一个是dd-mm-yyyy,一个是yyyy-mm-dd),首先要把日期列转为datetime类型并对齐格式:
import pandas as pd # 处理公司数据的日期列 df1['ipodate'] = pd.to_datetime(df1['ipodate'], format='%d-%m-%Y') # 可选:同步处理datadate,后续若有需求可直接使用 df1['datadate'] = pd.to_datetime(df1['datadate'], format='%d-%m-%Y') # 处理国债收益率数据的日期列,同时将日期设为索引以方便时间区间查询 df2['date'] = pd.to_datetime(df2['date']) df2 = df2.set_index('date').sort_index()
步骤2:高效计算区间均值
针对26074行的大数据量,推荐用滚动均值预计算+精准匹配的方法,避免逐行遍历的低效问题:
方法1:滚动均值预计算 + 时间匹配(高效首选)
先给国债收益率数据预计算滚动6个月的均值,再通过时间匹配关联到每个ipodate:
# 计算滚动6个月的均值,closed='left'表示排除ipodate当天的数据 df2['rolling_6m_dgs10_mean'] = df2['dgs10'].rolling(window='6M', closed='left').mean() # 重置索引,将日期转回列以便合并 df2_reset = df2.reset_index() # 对两个DataFrame按日期排序,确保merge_asof可以正确匹配 df1_sorted = df1.sort_values('ipodate') df2_sorted = df2_reset.sort_values('date') # 用merge_asof匹配ipodate之前最近的交易日的滚动均值 # direction='backward'表示取ipodate或之前最近的有效数据 result = pd.merge_asof(df1_sorted, df2_sorted, left_on='ipodate', right_on='date', direction='backward') # 将结果映射回原DataFrame,保留原行顺序 df1['pre_6m_dgs10_mean'] = result.set_index(df1.index)['rolling_6m_dgs10_mean']
方法2:直接计算指定区间均值(小数据量适用)
如果需要严格计算ipodate前6个月到ipodate前一天的精确均值,可使用apply逐行计算,但数据量大时速度会明显变慢:
def get_6m_avg(ipodate): # 计算6个月前的起始日期 start_date = ipodate - pd.DateOffset(months=6) # 筛选区间内的国债收益率数据并计算均值 interval_data = df2.loc[(df2.index >= start_date) & (df2.index < ipodate), 'dgs10'] return interval_data.mean() # 新增列存储结果 df1['pre_6m_dgs10_mean'] = df1['ipodate'].apply(get_6m_avg)
关键注意事项
- 日期格式必须统一,否则时间区间筛选和匹配会完全失效;
rolling(window='6M')是按日历月计算区间,更贴合“前6个月”的业务逻辑;若需要固定交易日数量,可替换为window=126(约6个月的交易日数);merge_asof的效率远高于apply,适合处理万级以上的数据量。
内容的提问来源于stack exchange,提问作者Marie-Pier St-Vincent
相关产品推荐
相关产品推荐

