如何基于DataFrame构建滚转曲线(Roll-off Profile)并支持任意多日期
嘿,这个需求太常见啦!做期限结构或者资产负债管理的时候经常会遇到——想要灵活生成任意数量未来日期的滚转曲线,又不想重复写一堆判断代码。我来给你分享一个简洁高效的解决方案,完全能满足你的需求~
灵活生成任意日期的滚转曲线(无需重复代码)
核心思路是把需要对比的未来日期封装成一个可自定义的列表,然后利用Pandas的向量化特性批量处理,不管你加多少个日期,代码都不用改。
步骤1:准备示例数据
先构造一个带Maturity Date列的DataFrame(你可以替换成自己的真实数据):
import pandas as pd import datetime as dt # 模拟你的DataFrame结构 data = { 'Asset ID': [101, 102, 103, 104, 105], 'Maturity Date': pd.to_datetime([ '2024-06-30', '2025-01-15', '2026-03-20', '2023-12-10', '2027-09-05' ]), 'Principal': [5000, 8000, 3000, 12000, 6000] } df = pd.DataFrame(data)
步骤2:定义任意数量的未来日期列表
你可以根据业务需求随时添加、删除或修改这个列表,日期格式统一为datetime对象就行:
# 这里可以放N个未来日期,想加多少加多少 future_check_dates = [ dt.datetime(2024, 1, 1), dt.datetime(2025, 1, 1), dt.datetime(2026, 1, 1), dt.datetime(2027, 1, 1), dt.datetime(2028, 1, 1) # 随便加新日期,代码不用改 ]
步骤3:批量生成滚转曲线数据
根据你的需求,有两种常用的输出方式:
方式一:保留每条记录的到期判断标记
如果需要给每条资产标记在各个未来日期是否未到期,可以批量添加列:
# 遍历日期列表,自动生成对应列 for check_date in future_check_dates: # 自定义列名,方便识别 col_label = f'Not Matured by {check_date.strftime("%Y-%m-%d")}' # 向量化判断,性能拉满 df[col_label] = df['Maturity Date'] > check_date
执行后,你的DataFrame会自动新增N列,每列对应一个未来日期的判断结果,完全不用重复写df['Maturity Date'] > 日期这类代码。
方式二:直接生成滚转曲线的统计结果
如果你的目标是统计每个未来日期的未到期资产规模(比如本金总额、资产数量),直接聚合即可:
# 初始化一个字典存结果 roll_off_stats = {} for check_date in future_check_dates: # 统计未到期的本金总和 outstanding_principal = df.loc[df['Maturity Date'] > check_date, 'Principal'].sum() # 统计未到期的资产数量 outstanding_count = df.loc[df['Maturity Date'] > check_date, 'Asset ID'].count() # 把结果存入字典,用日期字符串当键 date_str = check_date.strftime("%Y-%m-%d") roll_off_stats[date_str] = {'Outstanding Principal': outstanding_principal, 'Outstanding Count': outstanding_count} # 转成DataFrame,方便可视化或导出 roll_off_df = pd.DataFrame.from_dict(roll_off_stats, orient='index')
这样得到的roll_off_df就是标准的滚转曲线数据,以后只要修改future_check_dates列表,重新运行这段代码就能得到新的结果,完全不用改动核心逻辑。
为什么这个方法靠谱?
- 完全灵活:支持任意数量的未来日期,增删日期只改列表,不用碰判断逻辑
- 性能高效:用Pandas向量化操作替代逐行循环,大数据量下速度快很多
- 扩展性强:如果需要按行业、产品类型细分滚转曲线,只要在聚合时加个
groupby就行,核心思路不变
内容的提问来源于stack exchange,提问作者Number Logic
相关产品推荐
相关产品推荐

