【问题标题】:pandas lagged value of time series (previous year) for cohortpandas 队列的时间序列(上一年)的滞后值
【发布时间】:2020-05-31 17:42:37
【问题描述】:

对于以下数据框:

import pandas as pd

df = pd.DataFrame({
    'dt':[
        '2019-01-01',
        '2019-01-02',
        '2019-01-03',
        '2020-01-01',
        '2020-01-02',
        '2020-01-03',
        '2019-01-01',
        '2019-01-02',
        '2019-01-03',
        '2020-01-01',
        '2020-01-02',
        '2020-01-03'
    ],
    'foo': [1,2,3, 4,5,6, 1,5,3, 4,10,6],

    'category': [1,1,1,1,1,1,  2,2,2,2,2,2]
})

如何找到每个类别上一年的滞后值?

df['dt'] = pd.to_datetime(df['dt'])
display(df)

移动索引只会返回一个空结果,因此分配失败。

df['last_year'] = df[df.dt == df.dt - pd.offsets.Day(365)]

显然,加入 2019 年的月份和日期的数据是可行的 - 但似乎更麻烦。有没有更好的办法?

编辑

想要的结果:

dt  foo     category  last_year
2020-01-01  4   1      1
2020-01-02  5   1      2
2020-01-03  6   1      3
2020-01-01  4   2      1
2020-01-02  10  2      5
2020-01-03  6   2      3

【问题讨论】:

  • 你的预期输出是什么?

标签: python pandas time-series lag shift


【解决方案1】:

您可以在assign dt 列之后使用merge df 与pd.DateOffset 的差异。

print (df.merge(df.assign(dt=lambda x: x['dt']+pd.DateOffset(years=1)), 
                on=['dt', 'category'], 
                suffixes=('','_lastYear'), 
                how='left'))
           dt  foo  category  foo_lastYear
0  2019-01-01    1         1           NaN
1  2019-01-02    2         1           NaN
2  2019-01-03    3         1           NaN
3  2020-01-01    4         1           1.0
4  2020-01-02    5         1           2.0
5  2020-01-03    6         1           3.0
6  2019-01-01    1         2           NaN
7  2019-01-02    5         2           NaN
8  2019-01-03    3         2           NaN
9  2020-01-01    4         2           1.0
10 2020-01-02   10         2           5.0
11 2020-01-03    6         2           3.0

【讨论】:

  • 完全正确 - 正如问题中概述的那样,与去年的连接是可能的 - 但是有没有像滚动这样的更原生的方法?
  • @GeorgHeiler 你可以使用groupby 或者shift,但我看不出你之后如何与索引对齐。或者您需要为每个组创建一个map,但我认为它不会比这种方法更“明显”:) 或者至少我不知道如何!
  • @GeorgHeiler 与 groupby 并使用 @anky 的原始想法,你可以做 df['last_year'] = df.groupby(['category']).apply(lambda dfg: dfg['dt'].sub(pd.Timedelta('365D')).dt.date.map(dict(zip(dfg['dt'],dfg['foo'])))).reset_index(level=0, drop=True) 但我不确定它会更有效吗?
猜你喜欢
  • 1970-01-01
  • 2017-10-09
  • 2021-10-04
  • 1970-01-01
  • 1970-01-01
  • 2023-02-08
  • 2021-07-06
  • 2021-05-24
  • 2017-11-05
相关资源
最近更新 更多