基于日期匹配的DataFrame减法:计算资产超额收益
问题:基于日期匹配计算超额收益
任务
通过将df_A中的总收益减去df_B中的对应日期无风险利率,计算超额收益(公式:总收益 - 无风险利率 = 超额收益)。
问题
两个DataFrame(df_A与df_B)的长度、日期范围和结构均不相同,无法直接执行减法操作。以下是数据示例与期望结果:
当前数据
import pandas as pd import numpy as np data_A = np.array([['A', 2], ['A', 5], ['B', 8], ['B', -7], ['B', 2], ['B', 4], ['C', 3]]) index_A = np.array([['2003-01-31'], ['2004-02-28'], ['2003-01-31'], ['2004-02-28'], ['2008-06-30'], ['2010-03-31'], ['2003-01-31']]) df_A = pd.DataFrame(data=data_A, columns=['company', 'total return'], index=index_A) data_B = np.array([[0.5], [0.2], [0.3], [0.4], [0.1], [1.2]]) index_B = np.array([['2000-01-31'], ['2002-02-28'], ['2003-01-31'], ['2004-02-28'], ['2010-03-31'], ['2012-04-30']]) df_B = pd.DataFrame(data=data_B, columns=['risk-free rate'], index=index_B)
期望结果
data_C = np.array([['A', 1.7], ['A', 4.6], ['B', 7.7], ['B', -7.4], ['B', 2], ['B', 3.9], ['C', 2.7]]) index_C = np.array([['2003-01-31'], ['2004-02-28'], ['2003-01-31'], ['2004-02-28'], ['2008-06-30'], ['2010-03-31'], ['2003-01-31']]) df_C = pd.DataFrame(data=data_C, columns=['company', 'total return'], index=index_C)
核心需求
- 匹配两个DataFrame的日期,将对应日期的无风险利率从df_A的所有总收益中扣除(如df_A中2003-01-31的所有公司总收益均减去该日期的无风险利率);
- df_A中无对应日期的行(如2008-06-30)保持原数值不变;
- df_B中无对应总收益的日期(如2000-01-31)不参与计算。
已尝试过合并DataFrame和循环方法,寻求更优雅的解决方案。同时欢迎对提问方式提出改进建议。
解决方案
可以利用Pandas的向量化索引操作,高效完成日期匹配与计算,无需循环或复杂合并:
# 先将df_A的总收益转为数值类型(示例中为字符串,需转换) df_A['total return'] = pd.to_numeric(df_A['total return']) # 按df_A的索引重新匹配df_B的无风险利率,缺失日期填充0(保证原数值不变) matched_rates = df_B.reindex(df_A.index, fill_value=0)['risk-free rate'] # 计算超额收益 df_A['total return'] -= matched_rates # 输出结果 print(df_A)
该方案通过reindex方法快速对齐两个DataFrame的日期索引,利用Pandas的向量化运算完成批量减法,代码简洁且性能高效,避免了循环带来的冗余与性能损耗。
提问方式改进建议
- 可提前说明df_A中
total return列的数据类型(示例中为字符串,实际处理需转换,补充后能减少试错成本); - 若数据量较大,可补充说明数据规模,方便推荐更适配的性能优化方案;
- 可将期望结果中的关键差异(如2008-06-30数值未变化)单独标注,让需求更直观清晰。
内容的提问来源于stack exchange,提问作者9Morgan8
相关产品推荐
相关产品推荐

