用来自同一行但不同列的值填充字典

时间:2018-10-09 14:58:19

标签: python pandas dictionary dataframe

最近我一直在尝试映射一些值,因此我试图创建一个字典来这样做。奇怪的是我的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 :(得分:8)

您可以这样做:

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是一个整数。
  • 最后,您使用第二个for循环迭代rs的值

更新

按照@piRSquared的建议,您可以使用zip:

d = {r : p for rs, p in zip(df.rules, df.procedure) for r in rs}

答案 1 :(得分:5)

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's answer is very good。尽管我主张提倡所有有用的答案,但我希望我能再次赞扬他们的答案(-:

答案 2 :(得分:4)

使用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转换是不必要的:

  

提供了ChainMap类,用于快速链接许多   映射,因此可以将它们视为一个单元。通常很多   比创建新字典并运行多个update()更快   电话。

另请参阅What is the purpose of collections.ChainMap?

答案 3 :(得分:2)

您可以检查拼合列表

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}

答案 4 :(得分:1)

使用itertools.chainDataFrame.itertuples

dict(
    chain.from_iterable(
        ((rule, row.procedure) for rule in row.rules) for row in df.itertuples()
    )
)