使用 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_1
和 ID_2
以及 Week - 2
相匹配的值。
例如,对于数据框中具有 ID_1 = 26
、ID_2 = 1182
和 Week = 3
的行,我想匹配由 ID_1 = 26
索引的系列中的值, ID_2 = 1182
和 Week = 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
然后合并 df
与 saved_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
我有一个 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_1
和 ID_2
以及 Week - 2
相匹配的值。
例如,对于数据框中具有 ID_1 = 26
、ID_2 = 1182
和 Week = 3
的行,我想匹配由 ID_1 = 26
索引的系列中的值, ID_2 = 1182
和 Week = 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
然后合并 df
与 saved_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