Как создать новый столбец в кадре данных, используя словарь с несколькими ключами - PullRequest
0 голосов
/ 29 января 2020

У меня есть многоключевой словарь, который я хотел бы использовать для создания нового столбца в кадре данных. Сделать это с помощью одного ключевого кадра данных довольно просто, но я озадачен правильным синтаксисом для отправки двух значений в словарь.

Мне удалось использовать словарь с одним ключом с помощью map, get, и применить (пример карты)

    import pandas as pd      
    df = pd.DataFrame(data = {'Col1': [1, 2, 3, 4], 'Col2': ['A', 'B', 'C', 'D']})

    single_dict = {1: 'This', 2: 'is', 3: 'pretty', 4: 'easy'}

    df['newcol_a'] = df['Col1'].map(single_dict)

    print(df)```

, который возвращает ожидаемое "

    Col1 Col2 newcol_a
    0     1    A     This
    1     2    B       is
    2     3    C   pretty
    3     4    D     easy

Но когда я создаю многоключевой словарь, такой как

dbl_dict = {1: {'A': 'THIS', 'B': 'blah', 'C': 'blah', 'D': 'blah'},
            2: {'A': 'blah', 'B': 'HAS' , 'C': 'blah', 'D': 'blah'},
            3: {'A': 'blah', 'B': 'blah', 'C': 'ME'  , 'D': 'blah'},
            4: {'A': 'blah', 'B': 'blah', 'C': 'blah', 'D': 'STUMPED'},}

, я могу чтобы вызвать его, используя 'get'

dbl_dict.get(1, {}).get('A', 'Other')
Out[5]: 'THIS'      

Но я не могу понять синтаксис (пробовал около 40 разных вещей, таких как df['newcol_b'] = df[['Col1', 'Col2']].map(dbl_dict)), чтобы получить желаемые результаты:

    Col1 Col2 newcol_a
    0     1    A     THIS
    1     2    B      HAS
    2     3    C       ME
    3     4    D  STUMPED

Ответы [ 3 ]

2 голосов
/ 29 января 2020

map не знает, как обращаться с вложенным диктом. Если вы настаиваете на использовании этого диктата, вы можете использовать apply на всем фрейме данных, но вам необходимо создать пользовательскую функцию отображения:

import pandas as pd

df = pd.DataFrame(data={'Col1': [1, 2, 3, 4], 'Col2': ['A', 'B', 'C', 'D']})
dbl_dict = {1: {'A': 'THIS', 'B': 'blah', 'C': 'blah', 'D': 'blah'},
            2: {'A': 'blah', 'B': 'HAS', 'C': 'blah', 'D': 'blah'},
            3: {'A': 'blah', 'B': 'blah', 'C': 'ME', 'D': 'blah'},
            4: {'A': 'blah', 'B': 'blah', 'C': 'blah', 'D': 'STUMPED'}}

df['new_col'] = df.apply(lambda s: dbl_dict.get(s['Col1'], {}).get(s['Col2']), axis=1)

df теперь

   Col1 Col2  new_col
0     1    A     THIS
1     2    B      HAS
2     3    C       ME
3     4    D  STUMPED

Возможно решение с loc (или at) (и, если это так, вероятно, будет быстрее). Нужно разобраться в этом.

0 голосов
/ 29 января 2020

Самым простым вариантом, на мой взгляд, является создание нового DataFrame с использованием вашего вложенного словаря и снятие стека с этим DataFrame, который затем можно объединить с исходным DataFrame, например:

s = pd.DataFrame(dbl_dict).unstack().rename_axis(('Col1','Col2')).rename('new_column')
print (s)
df = df.join(s, on=['Col1','Col2'])
print (df)
0 голосов
/ 29 января 2020

Я создал крошечную (2-строчную) пользовательскую функцию для вас, которая, кажется, решает проблему. Конечно, это может быть улучшено, чтобы отлавливать некоторые ошибки и поведение для конкретных c случаев.

import pandas as pd
data = {'col_1':[1,2,3,4],'col_2':['A','B','C','D']}
df = pd.DataFrame(data)
dbl_dict = {1: {'A': 'THIS', 'B': 'blah', 'C': 'blah', 'D': 'blah'},
            2: {'A': 'blah', 'B': 'HAS' , 'C': 'blah', 'D': 'blah'},
            3: {'A': 'blah', 'B': 'blah', 'C': 'ME'  , 'D': 'blah'},
            4: {'A': 'blah', 'B': 'blah', 'C': 'blah', 'D': 'STUMPED'},}
def maperino(dict_name,key_1,key_2):
    val = [dict_name[key_1[i]][key_2[i]] for i in range(len(key_1))]
    return val        
df['col_3'] = maperino(dbl_dict,df['col_1'],df['col_2'])
print(df)

Вывод:

   col_1 col_2    col_3
0      1     A     THIS
1      2     B      HAS
2      3     C       ME
3      4     D  STUMPED
...