python - 根据契约(Contract)开始日期和结束日期表计算契约(Contract)天数

标签 python pandas

我有一个用于特定 Assets (A、B、...)的合约的 pandas 数据框。每个契约(Contract)都有开始日期、结束日期(包括两者)和日费率(契约(Contract)不能重叠)。我想生成一个表格,显示在指定期间(即日期范围,在本例中为季度)内每项 Assets 签订契约(Contract)的总天数。然后,我想计算每项 Assets 的总收入(日费率 * 契约(Contract)天数)。

我首先生成季度结束日期的列表,但不知道如何继续:

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

输出(分组后)

Asset    total_revs_20190930_20191231   total_revs_20200331_20200630    total_revs_20200930_20201231

A       64                              0                                0
B       0                               0                                0

关于python - 根据契约(Contract)开始日期和结束日期表计算契约(Contract)天数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58313964/

相关文章:

python - 如何从 python opencv 中的数组中读取原始 png?

python - tensorflow 错误 : "Cannot parse tensor from proto"

python - Pandas - 使用多个值填充 NaN

python - Pandas loc 返回的是系列而不是 df

python /dpkt : Find out if packet is a tcp packet or a udp packet ,

python - 直接索引一个numpy数组的时间复杂度是多少

python - 如果值是字符串列表,如何引用字典中的值?

python - 从行中提取每日值并使用日期创建新行

python - 如何评估一组行是否包含特定值?

python - Pandas - 添加一列以在 group-by 后唯一标识每个组