我正在尝试将2级聚合的结果映射到原始分类功能,并将其用作新功能。我这样创建了聚合。
temp_df = pd.concat([X_train[['cat1', 'cont1', 'cat2']], X_test[['cat1', 'cont1', 'cat2']]])
temp_df = temp_df.groupby(['cat1', 'cat2'])['cont1'].agg(['mean']).reset_index().rename(columns={'mean': 'cat1_cont1/cat2_Mean'})
然后,我根据第一和第二个分类特征的值制作了MultiIndex
,最后将新的聚合特征转换为dict
。
arrays = [list(temp_df['cat1']), list(temp_df['cat2'])]
temp_df.index = pd.MultiIndex.from_tuples(list(zip(*arrays)), names=['cat1', 'cat2'])
temp_df = temp_df['cat1_cont1/cat2_Mean'].to_dict()
dict键是作为多元索引的元组。元组中的第一个值是cat1的值,第二个值是cat2的值。
{(1000, 'C'): 23.443,
(1001, 'H'): 50.0,
(1001, 'W'): 69.5,
(1002, 'H'): 60.0,
(1003, 'W'): 42.95,
(1004, 'H'): 51.0,
(1004, 'R'): 150.0,
(1004, 'W'): 226.0,
(1005, 'H'): 50.0}
当我尝试将这些值映射到原始cat1功能时,一切都变成NaN。如何正确执行此操作?
X_train['cat1'].map(temp_df) # Produces a column of all NaNs
答案 0 :(得分:1)
您可以map
按多列,但有必要从原始列创建元组,此处按temp_df[['cat1', 'cat2']].apply(tuple, axis=1)
:
temp_df = pd.DataFrame({
'cat1':list('aaaabb'),
'cat2':[4,5,4,5,5,4],
'cont1':[7,8,9,4,2,3],
})
new = (temp_df.groupby(['cat1', 'cat2'])['cont1'].agg(['mean'])
.reset_index()
.rename(columns={'mean': 'cat1_cont1/cat2_Mean'}))
print (new)
cat1 cat2 cat1_cont1/cat2_Mean
0 a 4 8
1 a 5 6
2 b 4 3
3 b 5 2
arrays = [list(new['cat1']), list(new['cat2'])]
new.index = pd.MultiIndex.from_tuples(list(zip(*arrays)), names=['cat1', 'cat2'])
d = new['cat1_cont1/cat2_Mean'].to_dict()
print (d)
{('a', 4): 8, ('a', 5): 6, ('b', 4): 3, ('b', 5): 2}
temp_df['cat1_cont1/cat2_Mean'] = temp_df[['cat1', 'cat2']].apply(tuple, axis=1).map(d)
对于用聚合值填充的新列,请使用GroupBy.transform
函数:
temp_df['cat1_cont1/cat2_Mean1'] = temp_df.groupby(['cat1', 'cat2'])['cont1'].transform('mean')
另一种解决方案是Series with MultiIndex
使用DataFrame.join
:
s = temp_df.groupby(['cat1', 'cat2'])['cont1'].agg('mean').rename('cat1_cont1/cat2_Mean2')
temp_df = temp_df.join(s, on=['cat1', 'cat2'])
print (temp_df)
cat1 cat2 cont1 cat1_cont1/cat2_Mean cat1_cont1/cat2_Mean1 \
0 a 4 7 8 8
1 a 5 8 6 6
2 a 4 9 8 8
3 a 5 4 6 6
4 b 5 2 2 2
5 b 4 3 3 3
cat1_cont1/cat2_Mean2
0 8
1 6
2 8
3 6
4 2
5 3