基于回溯窗口扩展pandas数据框的行

问题描述 投票:0回答:1

给定以下形式的数据框:

日期 窗户
0 2009-01-01 00:00:00 2
1 2009-01-02 00:00:00 1
2 2009-01-03 00:00:00 3

可以通过以下方式生成

df = pd.DataFrame({'date': pd.date_range(start='20090101', end='20090103')})
df['window'] = [2, 1, 3]

目标是为“日期”的过去“窗口”内的每个“新日期”创建一行。以上面的数据框为例,结果应该是:

日期 窗户 回顾 新日期
0 2009-01-01 00:00:00 2 0 2009-01-01 00:00:00
0 2009-01-01 00:00:00 2 1 2008-12-31 00:00:00
0 2009-01-01 00:00:00 2 2 2008-12-30 00:00:00
1 2009-01-02 00:00:00 1 0 2009-01-02 00:00:00
1 2009-01-02 00:00:00 1 1 2008-12-31 00:00:00
2 2009-01-03 00:00:00 3 0 2009-01-03 00:00:00
2 2009-01-03 00:00:00 3 1 2009-01-02 00:00:00
2 2009-01-03 00:00:00 3 2 2008-12-31 00:00:00
2 2009-01-03 00:00:00 3 3 2008-12-30 00:00:00

到目前为止我的解决方案是

df['lookback'] = df['window'].apply(lambda x: range(x+1))
df = df.explode('lookback')
df['new_date'] = df[['date', 'lookback']].apply(lambda x: add_biz_dt(x[0], -x[1]), axis=1)

请注意,add_biz_dt() 是我的内部方法,它采用日期时间第一个参数和数字第二个参数,并获取相应的业务日期。我必须使用 add_biz_dt。

我正在努力改进它,使其更加高效。可能有比使用“爆炸”更好的方法,而“应用”方法似乎效率特别低。

pandas dataframe
1个回答
0
投票

一个可能的选项(没有自定义功能):

lookbacks = (
    pd.DataFrame(
        [
            [[(iw, d - pd.Timedelta(iw, unit="D"))
              for iw in range(0, w+1)]
             for d,w in df.to_numpy()]
        ])
    .T.explode(0)[0].apply(pd.Series)
    .set_axis(["lookback", "new_date"], axis=1)
)

out = df.join(lookbacks)

输出:

print(out)

        date  window  lookback   new_date
0 2009-01-01       2         0 2009-01-01
0 2009-01-01       2         1 2008-12-31
0 2009-01-01       2         2 2008-12-30
1 2009-01-02       1         0 2009-01-02
1 2009-01-02       1         1 2009-01-01
2 2009-01-03       3         0 2009-01-03
2 2009-01-03       3         1 2009-01-02
2 2009-01-03       3         2 2009-01-01
2 2009-01-03       3         3 2008-12-31
    
© www.soinside.com 2019 - 2023. All rights reserved.