Pandas - отображение индекса уровня 2 на столбец DataFrame - PullRequest
1 голос
/ 19 сентября 2019

Я пытаюсь сопоставить результаты агрегации на 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.

* 1007.*

Ключи 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 Ответ

1 голос
/ 19 сентября 2019

Вы можете 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')

Другим решением является использование DataFrame.join от Series with MultiIndex:

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  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...