Как можно переключить значение и ключ вложенного словаря в Python? - PullRequest
0 голосов
/ 23 января 2019

Я пишу алгоритм отложенного принятия для врачей и больниц, но прежде чем попасть туда, мне нужно, чтобы мои словари были представлены правильно.

В настоящее время у меня есть словарь врачей, содержащий вложенный словарь сих рейтинг больниц:

{'Doctor_7': {'Hospital_6': 4.0, 'Hospital_3': 8.0, 'Hospital_1': 10.0, 'Hospital_8': 1.0, 'Hospital_2': 9.0, 'Hospital_10': 5.5, 'Hospital_5': 5.5, 'Hospital_7': 2.0, 'Hospital_4': 7.0, 'Hospital_9': 3.0}

Здесь «Больница_6» обозначает больницу, а 4,0 указывает ее рейтинг этим конкретным врачом (в данном случае 4 из 10)

Из-за DataFrame изкоторый я сделал этот словарь он представлен в его нынешнем виде.Тем не менее, я хочу, чтобы размещение «Больница_6» и 4.0 поменялось.Следовательно, я хочу, чтобы 4.0 был ключом, а hospital_6 - его значением (из вложенного словаря).

Однако я не совсем знаю, как переключать эти два параметра.Если бы кто-нибудь мог мне помочь, это было бы очень признательно!

Ответы [ 3 ]

0 голосов
/ 23 января 2019

Вы можете использовать DICT понимания, чтобы добиться этого:

dict_ ={'Doctor_7': {'Hospital_6': 4.0, 'Hospital_3': 8.0, 'Hospital_1': 10.0, 'Hospital_8': 1.0, 'Hospital_2': 9.0, 'Hospital_10': 5.5, 'Hospital_5': 5.5, 'Hospital_7': 2.0, 'Hospital_4': 7.0, 'Hospital_9': 3.0 }}
new_dict = {key:{v:k for k,v in value.items()} for key, value in dict_.items()}
print(new_dict)

Чтобы узнать больше о понимании Dict: Следуйте этому

ПРИМЕЧАНИЕ. Он переопределит дубликаты ключей, значения которых были в предыдущем дикте. Если у вас есть две больницы с одинаковым рейтингом, вы получите только одну.


Выход:

{'Doctor_7': {4.0: 'Hospital_6',
  8.0: 'Hospital_3',
  10.0: 'Hospital_1',
  1.0: 'Hospital_8',
  9.0: 'Hospital_2',
  5.5: 'Hospital_5',
  2.0: 'Hospital_7',
  7.0: 'Hospital_4',
  3.0: 'Hospital_9'}}
0 голосов
/ 23 января 2019

Поскольку два решения до сих пор игнорируют заботу о дубликатах ключей (одинаковый рейтинг, присвоенный нескольким больницам), вот решение, которое делает.

Недостатком является то, что каждый рейтинг указывает на список больниц с таким рейтингом, а не на название, даже если этот список имеет длину один.

from collections import defaultdict

d = {'Doctor_7': {'Hospital_6': 4.0,
                  'Hospital_3': 8.0,
                  'Hospital_1': 10.0,
                  'Hospital_8': 1.0,
                  'Hospital_2': 9.0,
                  'Hospital_10': 5.5,
                  'Hospital_5': 5.5,
                  'Hospital_7': 2.0,
                  'Hospital_4': 7.0,
                  'Hospital_9': 3.0}}

new_d = {}
for doctor, ratings in d.items():
    ratings_inverse = defaultdict(list)
    for hospital, rating in ratings.items():
        ratings_inverse[rating].append(hospital)
    new_d[doctor] = dict(ratings_inverse)

print(new_d)
# {'Doctor_7': {1.0: ['Hospital_8'],
#   2.0: ['Hospital_7'],
#   3.0: ['Hospital_9'],
#   4.0: ['Hospital_6'],
#   5.5: ['Hospital_10', 'Hospital_5'],
#   7.0: ['Hospital_4'],
#   8.0: ['Hospital_3'],
#   9.0: ['Hospital_2'],
#   10.0: ['Hospital_1']}}

Но так как вы упоминаете фрейм данных, если это pandas.DataFrame, который выглядел так:

#                Doctor_1  Doctor_7
# Hospital_1          1.0      10.0
# Hospital_10         8.0       5.5
# Hospital_2          3.0       9.0
# Hospital_3         10.0       8.0
# Hospital_4          6.0       7.0
# Hospital_5          8.0       5.5
# Hospital_6          4.0       4.0
# Hospital_7          4.0       2.0
# Hospital_8          9.0       1.0
# Hospital_9          3.0       3.0

Вы можете сделать что-то вроде этого:

df.apply(lambda col: col.reset_index()\
                        .groupby(col.name)["index"]\
                        .apply(lambda x: x.tolist()))
#                        Doctor_1                   Doctor_7
# 1.0                [Hospital_1]               [Hospital_8]
# 2.0                         NaN               [Hospital_7]
# 3.0    [Hospital_2, Hospital_9]               [Hospital_9]
# 4.0    [Hospital_6, Hospital_7]               [Hospital_6]
# 5.5                         NaN  [Hospital_10, Hospital_5]
# 6.0                [Hospital_4]                        NaN
# 7.0                         NaN               [Hospital_4]
# 8.0   [Hospital_10, Hospital_5]               [Hospital_3]
# 9.0                [Hospital_8]               [Hospital_2]
# 10.0               [Hospital_3]               [Hospital_1]
0 голосов
/ 23 января 2019
old_dict = {'Doctor_7': {'Hospital_6': 4.0, 'Hospital_3': 8.0, 'Hospital_1': 10.0, 'Hospital_8': 1.0, 'Hospital_2': 9.0, 'Hospital_10': 5.5, 'Hospital_5': 5.5, 'Hospital_7': 2.0, 'Hospital_4': 7.0, 'Hospital_9': 3.0}

new_dict = {doctor: OrderedDict(sorted(((value, hospital) for hospital, value in values.items()), 
            key=lambda p: p[0])) 
            for doctor, values in old_dict.items()}

Выходы

{'Doctor_7': OrderedDict([(1.0, 'Hospital_8'),
              (2.0, 'Hospital_7'),
              (3.0, 'Hospital_9'),
              (4.0, 'Hospital_6'),
              (5.5, 'Hospital_5'),
              (7.0, 'Hospital_4'),
              (8.0, 'Hospital_3'),
              (9.0, 'Hospital_2'),
              (10.0, 'Hospital_1')])}
...