熊猫-将2级索引字典映射到DataFrame列

时间:2019-09-19 05:03:41

标签: python pandas numpy data-science

我正在尝试将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

1 个答案:

答案 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  
相关问题