我需要为不同债券的息票创建一个“日历”。想法如下:息票债券有三种类型。2第一种每年付息票,第二种每季度付息票,第三种每月付息票。3我有下表
表1
| 债券|类型|发布日期|到期日|
| - ------|- ------|- ------|- ------|
| 粘合A|每季|2022年1月1日|2032年1月1日|
| 粘合B|每月|2020年6月6日|二〇二五年六月六日|
在此表中,每行都是唯一的,每个焊接只出现一次,因此表中没有重复项。
最后我希望得到这样的表
表二
| 债券|类型|发布日期|到期日|息票日期|
| - ------|- ------|- ------|- ------|- ------|
| 粘合A|每季|2022年1月1日|2032年1月1日|2022年4月1日|
| 粘合A|每季|2022年1月1日|2032年1月1日|2022年7月1日|
| 粘合A|每季|2022年1月1日|2032年1月1日|二○二二年十月一日|
| 粘合A|每季|2022年1月1日|2032年1月1日|2023年1月1日|
显然,这个表格应该更长,但我希望预期结果的概念是明确的。
在这里我应该指出,我不需要日期与天的精度,我需要有正确的年份和月份,这就是为什么你会看到,我做了所有的优惠券日期与第一天的一个月。
我尝试使用pandom.Timedelta来完成这个任务,但是“M”(月)和“Y”(年)值被删除了,所以我不得不在没有它们的情况下处理。
我尝试完成以下任务:
我的进口
import numpy as np
import pandas as pd
import datetime
因此,表1是我的 Dataframe ,我根据键类型将其分为三个较小的帧。所有日期均为datetime 64 [ns]格式
annual_df = df[df.Type == 'Annually'].reset_index(drop = True)
quarter_ df = df[df.Type == 'Quarterly'].reset_index(drop = True)
month_df = df[df.Type == 'Monthly'].reset_index(drop = True)
这是我的代码为年息票债券我倒回去,因为在到期日coupond是肯定支付
temp = pd.DataFrame(columns={'Bond', 'Type', 'Release date', 'Maturity date', 'Coupon date'})
for i in annual_df.index:
stop_date = annual_df['Release date'][i]
_date = annual_df['Maturity date'][i] # the date that will be passed into 'Coupon date' column
c = 0 # a constant
print(i, 'out of', annual_df.index.max()) # to track the iteration
while _date > stop_date:
arr = {'Bond':annual_df.Bond[i], 'Type':annual_df.Type[i], 'Release date':stop_date,
'Maturity date':annual_df['Maturity date'][i], 'Coupon date': _date}
temp = temp.append(arr, ignore_index = True)
c += 1
_date = datetime.datetime(annual_df['Maturity date'][i].year - c, ['Maturity date'][i].month, 1)
annual_df = temp
所以,这段代码在我的数据集上运行了大约一个小时,这个数据集包含25000个不同的债券,这是相当多的,但是没有下面的季度支付券代码运行的时间长
temp = pd.DataFrame(columns={'Bond', 'Type', 'Release date', 'Maturity date', 'Coupon date'})
for i in quarter_df.index:
stop_date = quarter_df['Release date'][i]
_date = quarter_df['Maturity date'][i] # the date that will be passed into 'Coupon date' column
c = 0 # a constant
print(i, 'out of', quarter_df.index.max()) # to track the iteration
if quarter_df['Maturity date'][i].month < 4:
while _date > stop_date:
arr1 = {'Bond':annual_df.Bond[i], 'Type':annual_df.Type[i], 'Release date':stop_date,
'Maturity date':annual_df['Maturity date'][i], 'Coupon date': _date}
_date = datetime.datetime(annual_df['Maturity date'][i].year - c,
['Maturity date'][i].month + 3,1)
arr2 = {'Bond':annual_df.Bond[i], 'Type':annual_df.Type[i], 'Release date':stop_date,
'Maturity date':annual_df['Maturity date'][i], 'Coupon date': _date}
_date = datetime.datetime(annual_df['Maturity date'][i].year - c,
['Maturity date'][i].month + 6,1)
arr3 = {'Bond':annual_df.Bond[i], 'Type':annual_df.Type[i], 'Release date':stop_date,
'Maturity date':annual_df['Maturity date'][i], 'Coupon date': _date}
_date = datetime.datetime(annual_df['Maturity date'][i].year - c,
['Maturity date'][i].month + 9,1)
arr4 = {'Bond':annual_df.Bond[i], 'Type':annual_df.Type[i], 'Release date':stop_date,
'Maturity date':annual_df['Maturity date'][i], 'Coupon date': _date}
c += 1
_date = datetime.datetime(annual_df['Maturity date'][i].year - c,
['Maturity date'][i].month,1)
temp = temp.append(arr1, ignore_index=True)
temp = temp.append(arr2, ignore_index=True)
temp = temp.append(arr3, ignore_index=True)
temp = temp.append(arr4, ignore_index=True)
elif quarter_df['Maturity date'][i].month > 3 and quarter_df['Maturity date'][i].month < 7:
#the same if but just with different _date month values, literaly Ctrl+C, Ctrl+V
elif quarter_df['Maturity date'][i].month > 6 and quarter_df['Maturity date'][i].month < 10:
#again, the same
else:
#same
所以,根据我的计算,这部分每次迭代大约需要2秒,我有一个34000行的数据集,这个代码总共工作了18.3小时。
你知道如何优化这段代码吗?你知道有没有其他方法可以做同样的事情,但是更短更快?
1条答案
按热度按时间bejyjqdl1#
您可以为每行生成一系列息票日期,然后将其展开: