如何按 > 日期对一系列日期求和并将它们附加到熊猫新数据框中的新列?

Posted

技术标签:

【中文标题】如何按 > 日期对一系列日期求和并将它们附加到熊猫新数据框中的新列?【英文标题】:How to sum by > date for a range of dates and append them to a new column in a new dataframe in pandas? 【发布时间】:2019-11-07 15:12:36 【问题描述】:

我有一个类似于以下的数据集:

abbrev    amount    maturity
acct1     100       6/2/2019
acct1     500       6/3/2019
acct1     1100      6/5/2019
acct2     200       6/3/2019
acct3     1000      6/4/2019
acct4     2500      6/5/2019

我想要做的是有一个列表或日期范围。我尝试了以下方法:

accountDates = pd.date_range(start='6/1/2019', end='6/5/2019')

然后我想逐个循环遍历日期范围,并在成熟度大于日期时得到总和。例如,如果成熟度 > '6/1/2019',acct1 的总和为 1200。理想情况下,我希望将此信息存储在如下所示的新数据框中:

abbrev    6/1/2019    6/2/2019    6/3/2019    6/4/2019    6/5/2019
acct1     1700        1600        1100        1100        0
acct2     200         200         0           0           0
acct3     1000        1000        1000        0           0
acct4     2500        2500        2500        2500        0

但是我正在努力解决循环的机制如何工作,如果我能够使用带有聚合 sum 函数的 for 循环并让它通过日期,那么它将如何存储单个日期结果并将新列附加到新数据框?

编辑:向数据集添加了更多信息,以使用例(请参阅:acct1)更清晰(希望如此)从日期范围列表中。

【问题讨论】:

【参考方案1】:

您可以使用pivot_table,然后使用reindex 颠倒日期列表,并使用cumsum 加上shift 来获得一天的总和。然后reindex 再次以正确的顺序列出日期。

print (df.pivot_table(values='amount', index='abbrev', 
                      columns='maturity', aggfunc=sum, fill_value=0)
          .reindex(columns=accountDates[::-1])
          .cumsum(axis=1)
          .shift(axis=1)
          .reindex(columns=accountDates)
          .fillna(0))
       2019-06-01  2019-06-02  2019-06-03  2019-06-04  2019-06-05
abbrev                                                            
acct1       1700.0      1600.0      1100.0      1100.0         0.0
acct2        200.0       200.0         0.0         0.0         0.0
acct3       1000.0      1000.0      1000.0         0.0         0.0
acct4       2500.0      2500.0      2500.0      2500.0         0.0

【讨论】:

我相信这可能已经做到了!立即针对手动计算进行测试。 看起来唯一的问题是它不会计算任何不在 accountDates 中的总和,理想情况下,只要它大于 accountDates 日期,它甚至会在未来很远的地方计算。在短期内,虽然我可以将我的 accountDates 列表调整到最远的日期。 这也奇怪地跳过了几天,我不知道为什么。会有一堆天的完整聚合,然后 1-2 或 2-3 天有 0,然后它开始再次正确聚合剩余的天。不确定为什么会这样,但想弄清楚。 @Ric 不确定我是否理解,也许第一个重新索引可能是:reindex(columns=pd.date_range(start=df.maturity.min(), end=df.maturity.max())[::-1], fill_value=0) 以获取所有日期,然后将 accountDates 保留在第二个重新索引中【参考方案2】:

你需要groupby,然后是pivot_table

df['maturity'] = df['maturity'] - pd.Timedelta(days=1)
mdata = df.groupby(['maturity', 'abbrev']).sum().reset_index(1).reindex(accountDates)
pdf = pd.pivot_table(mdata.dropna(), index='abbrev', columns=mdata.dropna().index).bfill(1).fillna(0)

输出:

       amount                                 
       2019-06-01 2019-06-02 2019-06-03 2019-06-04
abbrev                                            
acct1      1200.0        0.0        0.0        0.0
acct2       200.0      200.0        0.0        0.0
acct3      1000.0     1000.0     1000.0        0.0
acct4      2500.0     2500.0     2500.0     2500.0

【讨论】:

得到错误标志:“ValueError: cannot reindex from a duplicate axis” groupby了吗? @Ric groupby line 建议是我得到错误的地方。 不可能。 Group by 负责处理重复项并将它们组合在一起。【参考方案3】:

另一个使用joinpivot 的镜头:

(df[['abbrev','maturity']].join(df.sort_values(['abbrev','maturity'], ascending=False)
                                  .groupby(['abbrev'])
                                  .cumsum())
                          .pivot(index='abbrev', columns='maturity', values='amount')
                          .reindex(columns=accountDates)
                          .shift(-1, axis=1)
                          .bfill(1)
                          .fillna(0))

【讨论】:

以上是关于如何按 > 日期对一系列日期求和并将它们附加到熊猫新数据框中的新列?的主要内容,如果未能解决你的问题,请参考以下文章

遍历目录树并将日期戳附加到文件名

Oracle Query 按另一个表中的每个日期范围对一列求和

核心日期一对一排序

BIGQUERY - 如何按特定日期使用求和函数?

在Python中按日期合并行和求和值[重复]

在 R 中:如何在两个日期之间按组对变量求和