从 table 的条件检查中填充空数据框

Populating empty data frame from conditional checks on a table

我正在寻找解决此问题的方法。

我有一个table‘年度合约’

其中,有以下几类数据:

1年金额 Year1Payday Year2Amount Year2Payday Year3Amount 第三年发薪日
1000.0 2020-08-01 1000.0 2021-08-01 1000.0 2022-08-01
2400.0 2021-06-01 3400.0 2022-06-01 4400.0 2023-06-01
1259.0 2019-05-01 1259.0 2020-05-01 1259.0 2021-05-01
2150.0 2021-08-01 2150.0 2022-08-01 2150.0 2023-08-01

etc,这范围长达 5 年,380 多行,有四种类型的客户(各自的 tables 设置与上述类似):年度支付,双年支付, 季付和月付。

我还有一个空数据框 (SumsOfPayments),其中包含基于每月更新的变量的索引和基于上述客户类型的列。

看起来像这样:

每年 双年度 每季度 每月
12 个月前
11 个月前
10 个月前

等等,直到它到达未来 60 个月。

SumOfPayments 和 YearXPaydays 上的索引都设置为各自月份的 1 号,因此它们可以 == 匹配。

(作为如何在 SumOfPayments table 上设置索引变量的示例):

12个月前 = datetime.today().replace(day=1,hour=0,minute=0).replace(second=0,microsecond=0)+relativedelta(months=-12)

因此,如果今天的日期是 2021 年 8 月 13 日,则以上将产生 2020-08-01 00:00:00。

这背后的意图是什么:

  1. 按日期排序年份X发薪日,总计年份X金额该分组日期

  2. 根据这些分组总和,检查 SumOfPayments 数据框上的索引,并在日期匹配的地方输入总和

示例(基于上面的 tables)

年度合同:

1年金额 Year1Payday Year2Amount Year2Payday Year3Amount 第三年发薪日
1000.0 2020-08-01 1000.0 2021-08-01 1000.0 2022-08-01
2400.0 2021-06-01 3400.0 2022-06-01 4400.0 2023-06-01
1259.0 2019-05-01 1259.0 2020-05-01 1259.0 2021-05-01
2150.0 2021-08-01 2150.0 2022-08-01 2150.0 2023-08-01

付款总和:

每年 双年度 每季度 每月
12 个月前 1000.0
11 个月前
10 个月前
9 个月前
8 个月前
7 个月前
6 个月前
5 个月前
4 个月前
3个月前 1259.0
2 个月前 2400.0
1个月前
currentmont 3150.0

如有任何帮助,我们将不胜感激,在此先感谢您的帮助。

如果您的列名称稍有不同,您可以使用 wide_to_long。相反,我将拆分并熔化它们以获得正确形状的数据。如果你很好奇发生了什么,只需打印出 dtamt 看看它们融化后的样子。

然后您可以使用 13 个周期(本月加上过去 12 个月)创建输出 table,并从去年的月初开始。

您可以为您想要的每个聚合级别创建多个 table,每年、每半年等。然后只需将它们合并到具有日期范围的 table。

import pandas as pd
from datetime import date, timedelta, date

df = pd.DataFrame({'Year1Amount': {0: 1000.0, 1: 2400.0, 2: 1259.0, 3: 2150.0},
 'Year1Payday': {0: '2020-08-01',
  1: '2021-06-01',
  2: '2019-05-01',
  3: '2021-08-01'},
 'Year2Amount': {0: 1000.0, 1: 3400.0, 2: 1259.0, 3: 2150.0},
 'Year2Payday': {0: '2021-08-01',
  1: '2022-06-01',
  2: '2020-05-01',
  3: '2022-08-01'},
 'Year3Amount': {0: 1000.0, 1: 4400.0, 2: 1259.0, 3: 2150.0},
 'Year3Payday': {0: '2022-08-01',
  1: '2023-06-01',
  2: '2021-05-01',
  3: '2023-08-01'}})

hist = pd.DataFrame({'Date':pd.date_range(start=(date.today() - timedelta(days=365)).replace(day=1),
                                          freq=pd.offsets.MonthBegin(),
                                          periods=13)})



# Split and melt
dt = df[[x for x in df.columns if 'Payday' in x]].melt(value_name='Date')
amt = df[[x for x in df.columns if 'Amount' in x]].melt(value_name='Annual')

# Combine and make datetime
df = pd.concat([amt['Annual'], dt['Date']],axis=1)
df['Date'] = pd.to_datetime(df['Date'])


# Do all of your aggregations into new dataframes like such, you'll need one for each column
# here's how to do the annual one
annual_sum = df.groupby('Date', as_index=False).sum()

# For each aggregation, merge to the hist df
hist = hist.merge(annual_sum, on='Date', how='left')

输出

         Date  Annual
0  2020-08-01  1000.0
1  2020-09-01     NaN
2  2020-10-01     NaN
3  2020-11-01     NaN
4  2020-12-01     NaN
5  2021-01-01     NaN
6  2021-02-01     NaN
7  2021-03-01     NaN
8  2021-04-01     NaN
9  2021-05-01  1259.0
10 2021-06-01  2400.0
11 2021-07-01     NaN
12 2021-08-01  3150.0