【问题标题】:Fill dictionary with value from the same row, but different column用同一行但不同列的值填充字典
【发布时间】:2019-03-14 09:50:32
【问题描述】:

最近我一直在尝试映射一些值,所以我正在尝试创建一个字典来做到这一点。奇怪的是我的 DataFrame 有一个由列表组成的列,而 DataFrame 与列表总是有点尴尬。 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 相当大,我无法手动完成。

【问题讨论】:

  • 我会从 MVCE 开始,包括输入/​​输出/预期输出。
  • 只是想确保我完全理解。对应的procedure 列中的值表示您想要处理的列表的索引?到底做什么?
  • IIUC,您想从这个数据框创建一个字典,以便从rules 列中的列表中获取键,并且关联的值来自procedure 列?
  • rahl23 您确实理解正确。我试图在我的编辑中澄清一点

标签: python pandas dictionary dataframe


【解决方案1】:

使用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?

【讨论】:

  • ChainMap 对我来说是新手。谢谢
  • 实际上,我了解到您可以在map 中将多个迭代作为附加参数传递。我从这篇文章中学到了两件事。希望我有两票(-:因此我更新了我的帖子。
【解决方案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}

【讨论】:

    【解决方案3】:

    使用itertools.chain 和DataFrame.itertuples:

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

    【讨论】:

      【解决方案4】:

      来自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。虽然我主张投票所有有用的答案,但我希望我能再次投票他们的答案(-:

      【讨论】:

        【解决方案5】:

        你可以这样做:

        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}
        

        【讨论】:

        • 这就像 Python 一样。它实际上就像一个魅力!唯一的问题是我不太了解代码。要求对这里发生的事情进行一点解释会不会要求太多?
        • 我会试着解释一下!
        • 使用values 并不是最通用的方法。在某些情况下,可能会导致问题。我会为您的解决方案这样做{i: j for I, j in zip(df.rules, df.procedure) for i in I}
        猜你喜欢
        • 2015-07-10
        • 1970-01-01
        • 2015-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多