【问题标题】:Populating empty data frame from conditional checks on a table通过对表的条件检查填充空数据框
【发布时间】:2021-10-16 21:08:14
【问题描述】:

我正在寻找有关如何解决此问题的一些方法。

我有一张表“AnnualContracts”

其中,有以下几种数据:

Year1Amount Year1Payday Year2Amount Year2Payday Year3Amount Year3Payday
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

等等,这个范围长达 5 年,超过 380 行,有四种类型的客户(他们自己的表设置与上面类似):年付、半年付、季度付和月付。

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

看起来像这样:

Annual Bi-Annual Quarterly Monthly
12monthsago
11monthsago
10monthsago

等到未来 60 个月。

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

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

12monthsago = 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 数据框上的索引,然后在日期匹配的地方输入总和

示例(基于上表)

年度合同:

Year1Amount Year1Payday Year2Amount Year2Payday Year3Amount Year3Payday
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

支付总额:

Annual Bi-Annual Quarterly Monthly
12monthsago 1000.0
11monthsago
10monthsago
9monthsago
8monthsago
7monthsago
6monthsago
5monthsago
4monthsago
3monthsago 1259.0
2monthsago 2400.0
1monthsago
currentmont 3150.0

非常感谢您对此的任何帮助,在此先感谢您的帮助。

【问题讨论】:

    标签: python pandas datetime pandas-groupby sumifs


    【解决方案1】:

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

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

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

    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
    

    【讨论】:

    • 抱歉时间回复,我已经花时间研究你在这里使用的功能,非常有用的东西。谢谢
    猜你喜欢
    • 2020-08-11
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 2016-01-21
    • 2019-03-17
    相关资源
    最近更新 更多