使用 Pandas 数据框添加 MultiIndex 系列的滞后特征

Use Pandas dataframe to add lag feature from MultiIindex Series

我有一个 MultiIndex 系列(3 个索引),如下所示:

Week   ID_1    ID_2
3       26     1182            39.0
               4767            42.0
               31393           20.0
               31690           42.0
               32962            3.0
....................................

我还有一个数据框 df,其中包含上面系列中用于索引的所有列(以及更多列),我想在我的数据框 df 中创建一个新列,其中包含与系列中的 ID_1ID_2 以及 Week - 2 相匹配的值。

例如,对于数据框中具有 ID_1 = 26ID_2 = 1182Week = 3 的行,我想匹配由 ID_1 = 26 索引的系列中的值, ID_2 = 1182Week = 1 (3-2) 并将其放在新列的该行上。此外,我的系列可能不一定具有数据框所需的值,在这种情况下我只想有 0.

现在,我正在尝试使用:

[multiindex_series.get((x[1].get('week', 2) - 2, x[1].get('ID_1', 0), x[1].get('ID_2', 0))) for x in df.iterrows()]

然而,这非常慢并且需要内存,我想知道有什么更好的方法来做到这一点。

FWIW,该系列是使用

创建的
saved_groupby = df.groupby(['Week', 'ID_1', 'ID_2'])['Target'].median()

如果存在更好的路径来创建我正在寻找的东西,我愿意以不同的方式进行。

Week 增加 2:

saved_groupby = df.groupby(['Week', 'ID_1', 'ID_2'])['Target'].median()
saved_groupby = saved_groupby.reset_index()
saved_groupby['Week'] = saved_groupby['Week'] + 2

然后合并 dfsaved_groupby:

result = pd.merge(df, saved_groupby, on=['Week', 'ID_1', 'ID_2'], how='left')

这将增加 df 2 周前的目标中位数。 要在没有匹配项时使中位数(目标)saved_groupby 列为 0,请使用 fillna 将 NaN 更改为 0:

result['Median'] = result['Median'].fillna(0)

例如,

import numpy as np
import pandas as pd
np.random.seed(2016)

df = pd.DataFrame(np.random.randint(5, size=(20,5)), 
                  columns=['Week', 'ID_1', 'ID_2', 'Target', 'Foo'])

saved_groupby = df.groupby(['Week', 'ID_1', 'ID_2'])['Target'].median()
saved_groupby = saved_groupby.reset_index()
saved_groupby['Week'] = saved_groupby['Week'] + 2
saved_groupby = saved_groupby.rename(columns={'Target':'Median'})

result = pd.merge(df, saved_groupby, on=['Week', 'ID_1', 'ID_2'], how='left')
result['Median'] = result['Median'].fillna(0)
print(result)

产量

    Week  ID_1  ID_2  Target  Foo  Median
0      3     2     3       4    2     0.0
1      3     3     0       3    4     0.0
2      4     3     0       1    2     0.0
3      3     4     1       1    1     0.0
4      2     4     2       0    3     2.0
5      1     0     1       4    4     0.0
6      2     3     4       0    0     0.0
7      4     0     0       2    3     0.0
8      3     4     3       2    2     0.0
9      2     2     4       0    1     0.0
10     2     0     4       4    2     0.0
11     1     1     3       0    0     0.0
12     0     1     0       2    0     0.0
13     4     0     4       0    3     4.0
14     1     2     1       3    1     0.0
15     3     0     1       3    4     2.0
16     0     4     2       2    4     0.0
17     1     1     4       4    2     0.0
18     4     1     0       3    0     0.0
19     1     0     1       0    0     0.0