Заполнить словарь значением из той же строки, но из другого столбца - PullRequest
0 голосов
/ 09 октября 2018

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

    rules          procedure
['10','11','12']       1
['13','14']            2
['20','21','22','24']  3

Поэтому я хочу создать словарь, который отображает «10» в 1, «14» в 2 и так далее.Я попробовал следующее:

dicc=dict()
for j in df['rules']:
    for i,k in zip(j,df.procedure):
        dicc[i]=k

Но это не сработало.Вероятно, что-то делать с индексами.Чего мне не хватает?

Редактировать: я пытаюсь создать словарь, который сопоставляет значения «10», «11», «12» с 1;«13», «14» - 2;«20», «21», «22», «24» - 3, поэтому, если я наберу dicc['10'], я получу 1, если я наберу dicc['22'], я получу 3.Очевидно, что фактический DataFrame намного больше, и я не могу сделать это вручную.

Ответы [ 5 ]

0 голосов
/ 09 октября 2018

с использованием itertools.chain и DataFrame.itertuples:

dict(
    chain.from_iterable(
        ((rule, row.procedure) for rule in row.rules) for row in df.itertuples()
    )
)
0 голосов
/ 09 октября 2018

Использование collections.ChainMap:

from collections import ChainMap

res = dict(ChainMap(*map(dict.fromkeys, df['rules'], df['procedure'])))

print(res)

{'10': 1, '11': 1, '12': 1, '13': 2, '14': 2,
 '20': 3, '21': 3, '22': 3, '24': 3}

Для многих случаев окончательное преобразование dict не требуется:

A ChainMapКласс предназначен для быстрой связи нескольких отображений, чтобы их можно было рассматривать как единое целое.Это часто намного быстрее, чем создание нового словаря и выполнение нескольких вызовов update().

См. Также Какова цель коллекций. ChainMap?

0 голосов
/ 09 октября 2018

Вы можете сделать это так:

import pandas as pd

data = [[['10', '11', '12'], 1],
        [['13', '14'], 2],
        [['20', '21', '22', '24'], 3]]

df = pd.DataFrame(data=data, columns=['rules', 'procedure'])

d = {r : p for rs, p in df[['rules', 'procedure']].values for r in rs}
print(d)

Вывод

{'20': 3, '10': 1, '11': 1, '24': 3, '14': 2, '22': 3, '13': 2, '12': 1, '21': 3}

Примечания:

  • Код {r : p for rs, p in df[['rules', 'procedure']].values for r in rs} является словарным пониманием, словарным аналогом списка.
  • df[['rules', 'procedure']].values эквивалентен zip(df.rules, df.procedure), он выводит пару списка, int.Таким образом, переменная rs представляет собой список, а p - целое число.
  • Наконец, вы перебираете значения rs, используя второй цикл for

ОБНОВЛЕНИЕ

Как предложено для @piRSquared, вы можете использовать zip:

d = {r : p for rs, p in zip(df.rules, df.procedure) for r in rs}
0 голосов
/ 09 октября 2018

Справка от cytoolz

from cytoolz.dicttoolz import merge

merge(*map(dict.fromkeys, df.rules, df.procedure))

{'10': 1,
 '11': 1,
 '12': 1,
 '13': 2,
 '14': 2,
 '20': 3,
 '21': 3,
 '22': 3,
 '24': 3}

Примечание

Я обновил свой пост, чтобы имитировать, как @jpp передавал несколько итераций в map. @ jpp очень хороший ответ .Хотя я бы выступил за отказ от всех полезных ответов, я бы хотел, чтобы я снова проголосовал за их ответ (-:

0 голосов
/ 09 октября 2018

Вы можете проверить выравнивание списка

dict(zip(sum(df.rules.tolist(),[]),df.procedure.repeat(df.rules.str.len())))
Out[60]: 
{'10': 1,
 '11': 1,
 '12': 1,
 '13': 2,
 '14': 2,
 '20': 3,
 '21': 3,
 '22': 3,
 '24': 3}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...