我有一个看起来像这样的Pandas数据框:

groupvar1 groupvar2 time value
1         1         1    5
1         1         2    8
1         1         3    9
1         1         4    12
1         1         5    19
1         2         1    5
1         2         2    8
1         2         3    9


并且我想在每个groupvar1 x groupvar2组合中创建一些自回归项,这样我最终得到:

groupvar1 groupvar2 time value t1 t2 t3
1         1         1    5     5  5  5
1         1         2    8     5  5  5
1         1         3    9     8  5  5
1         1         4    12    9  8  5
1         1         5    19    12 9  8
1         2         1    5     5  5  5
1         2         2    8     5  5  5
1         2         3    9     8  5  5


基本上,我在t1对象的每个组内创建三个自回归项t2t3groupby。如果结果为NaN,则从当前值回填。我要做的代码是:

for name, group in df.groupby(['groupvar1', 'groupvar2']):
    for i in range(1, 4):
            group.loc[:,'t' + str(i)] = group.sort_values(by=['time'])['value'].shift(i).fillna(method='ffill').fillna(method='bfill').values


问题在于,在大型数据集上,这非常慢。有没有一种方法可以使用内置的Pandas方法,该方法可能比这快?例如,改用.apply吗?

最佳答案

您无需弄乱groupby对象。最后,看来您的条件是groupvar2单元格应该等于i元素中的groupvar2单元格。这就是您要寻找的:

import pandas as pd
groupvar1 = pd.Series([1]*8, name='groupvar1')
groupvar2 = pd.Series([1,1,1,1,1,2,2,2], name='groupvar2')
time = pd.Series([1,2,3,4,5,1,2,3], name='time')
value = pd.Series([5,8,9,12,19,5,8,9], name='value')
df = pd.concat([groupvar1, groupvar2, time, value], axis=1)
data = [df]
for i in range(1,4):
    temp = df.loc[df['groupvar2'] == df['groupvar2'].shift(-i)]['value']
    temp.name = 't' + str(i)
    data.append(temp.reindex_like(df).shift(i))
res = pd.concat(data, axis=1).bfill()
print(res)

   groupvar1  groupvar2  time  value    t1   t2   t3
0          1          1     1      5   5.0  5.0  5.0
1          1          1     2      8   5.0  5.0  5.0
2          1          1     3      9   8.0  5.0  5.0
3          1          1     4     12   9.0  8.0  5.0
4          1          1     5     19  12.0  9.0  8.0
5          1          2     1      5   5.0  5.0  NaN
6          1          2     2      8   5.0  5.0  NaN
7          1          2     3      9   8.0  5.0  NaN


尽管由于移位的原因,您应该在最后仔细检查数据(请注意,最后一列的末尾有NaN)。

08-24 16:09