python - 根据合同开始和结束日期表计算合同天数
问题描述
我有一个pandas
特定资产(A、B、...)的合同数据框。每个合同都有一个开始日期、结束日期(包括两个日期)和一个日期(合同不能重叠)。我想生成一个表格,显示在指定期间(即日期范围,在本例中为季度)内的总天数,每项资产都已签订合同。然后,我想计算每项资产的总收入(日费率 * 合同天数)。
我首先生成了一个季度的结束日期列表,但不知道如何继续:
pd.date_range(start='9/30/2019',end='12/31/2020',freq='Q').tolist()
这是我的示例数据:
pd.DataFrame([['A', pd.to_datetime('07/30/2019'), pd.to_datetime('08/25/2019'), 5], ['B', pd.to_datetime('08/30/2022'), pd.to_datetime('09/30/2019'), 10], ['A',pd.to_datetime('09/30/2019'),pd.to_datetime('10/31/2019'), 2]], columns=['Asset', 'start', 'end', 'dayrate']).set_index('Asset')
start end dayrate
Asset
A 2019-07-30 2019-08-25 5
B 2022-08-30 2019-09-30 10
A 2019-09-30 2019-10-31 2
解决方案
如果我正确理解了问题陈述,这应该有效。
# create the dates for each quarter
date_range_quarter_lst = pd.date_range(start='9/30/2019',end='12/31/2020', freq='Q').tolist()
# create tuples of those dates
def pairwise(iterable):
it = iter(iterable)
a = next(it, None)
for b in it:
yield (a, b)
a = b
date_range_quarter_zip = [*pairwise(date_range_quarter_lst)]
# extract day by day views between the start and end dates
date_range_days = [pd.date_range(start=_[0], end=_[1], freq='d').tolist() for _ in date_range_quarter_zip]
# function to get the total revenue for the intersection of days
def get_day_count(row, date_range):
# get all days worked by the contracter between their start and end date
day_dates = pd.date_range(start=row['start'],end=row['end'], freq='d').tolist()
# set this with the specified date range and multiply by the day rate
return len(set(day_dates).intersection(set(date_range))) * row['dayrate']
rev_cols = []
# iterate over each period (quarter) and create a new column
for date_range in date_range_days:
col_nm = f"total_revs_{date_range[0].strftime('%Y%m%d')}_{date_range[-1].strftime('%Y%m%d')}"
df[col_nm] = df.apply(lambda row: get_day_count(row, date_range), axis=1)
rev_cols.append(col_nm)
# groupby
df.groupby(df.index)[rev_cols].sum()
输出(前分组)
start end dayrate total_revs_20190930_20191231 total_revs_20200331_20200630 total_revs_20200930_20201231
Asset
A 2019-07-30 2019-08-25 5 0 0 0
B 2022-08-30 2019-09-30 10 0 0 0
A 2019-09-30 2019-10-31 2 64 0 0
输出(发布 groupby)
Asset total_revs_20190930_20191231 total_revs_20200331_20200630 total_revs_20200930_20201231
A 64 0 0
B 0 0 0
推荐阅读
- javascript - React - 在两个现有组件之间渲染组件
- python - 如何使用 OCR 检测图像中的下标数字?
- javascript - 在函数中获取服务器的所有成员| 属性成员未定义 | 包:不和谐赠品
- ios - 更新后的 Apple Developer Program 许可协议需要审核。找不到任何同意接受
- laravel - 在 updateOrCreate 中使用条件语句
- python - Kivy Scrollview 中的图像不可滚动
- javascript - 我可以在没有任何服务器的情况下发送 XHR 请求吗?
- python - 在 Altair 的每个方面子图中显示 x 和 y 标签
- node.js - 如何在猫鼬中获取最新插入的记录_id
- python - 无法将 Django 与 mongoDb 连接