首页 > 解决方案 > 如何为 Pandas 数据框中的不平衡面板生成滞后变量?

问题描述

对于不平衡的面板数据,我很难生成滞后变量,尤其是滞后长度大于2。例如,我有一个数据集是不平衡的面板数据。该任务的目标是生成一个滞后 2 个月的变量。

import pandas as pd
import numpy as np 

a=[[1,'1990/1/1',1],
[1,'1990/2/1',2],
[1,'1990/3/1',3],
[2,'1989/12/1',3],
[2,'1990/1/1',3],
[2,'1990/2/1',4],
[2,'1990/3/1',5.5],
[2,'1990/4/1',5],
[2,'1990/6/1',6]]

data=pd.DataFrame(a,columns=['id','date','value'])
data['date']=pd.to_datetime(data['date'])

目前,我的解决方案是

data['lag2value']=np.where((data.groupby('id')['date'].diff(2)/np.timedelta64(1, 'M')).fillna(0).round()==2,
        data.sort_values(['id','date']).groupby('id')['value'].shift(2),np.nan)

但是,对于最后一个 obs,它确实有两个月的滞后观察,也就是说日期1990-6-1对应于1990-4-1. 我的代码无法弄清楚。

   id       date  value  lag2value
0   1 1990-01-01    1.0        NaN
1   1 1990-02-01    2.0        NaN
2   1 1990-03-01    3.0        1.0
3   2 1989-12-01    3.0        NaN
4   2 1990-01-01    3.0        NaN
5   2 1990-02-01    4.0        3.0
6   2 1990-03-01    5.5        3.0
7   2 1990-04-01    5.0        4.0
8   2 1990-06-01    6.0        NaN

一种可能的解决方案是构建一个作为平衡面板数据集的完整日期表,并将当前表合并到其中。但是,如果工作数据很大,则处理完整的表会很耗时。

我想知道这个问题的任何优雅的解决方案?提前致谢。

标签: pythonpandasdataframedatetime

解决方案


利用:

val = df.set_index('date').groupby('id').resample('MS').asfreq()['value']
val  = val.groupby(level=0).shift(2) 
df['lag2val'] = df.set_index(['id', 'date']).index.map(val)

细节:

步骤 A:使用DataFrame.groupbyonid和 usegroupby.resample使用每月开始频率对分组帧重新采样。

print(val)
id  date      
1   1990-01-01    1.0
    1990-02-01    2.0
    1990-03-01    3.0
2   1989-12-01    3.0
    1990-01-01    3.0
    1990-02-01    4.0
    1990-03-01    5.5
    1990-04-01    5.0
    1990-05-01    NaN
    1990-06-01    6.0
Name: value, dtype: float64

步骤 B:使用Series.groupbyonlevel=0将系列valshift2 个期间分组以创建滞后2月份val系列。

print(val)
id  date      
1   1990-01-01    NaN
    1990-02-01    NaN
    1990-03-01    1.0
2   1989-12-01    NaN
    1990-01-01    NaN
    1990-02-01    3.0
    1990-03-01    3.0
    1990-04-01    4.0
    1990-05-01    5.5
    1990-06-01    5.0
Name: value, dtype: float64

步骤 C:最后,使用set_indexwithSeries.map将新的滞后val系列映射到原始数据框df

print(df)
   id       date  value  lag2val
0   1 1990-01-01    1.0      NaN
1   1 1990-02-01    2.0      NaN
2   1 1990-03-01    3.0      1.0
3   2 1989-12-01    3.0      NaN
4   2 1990-01-01    3.0      NaN
5   2 1990-02-01    4.0      3.0
6   2 1990-03-01    5.5      3.0
7   2 1990-04-01    5.0      4.0
8   2 1990-06-01    6.0      5.0

推荐阅读