【问题标题】:Create data frame column that maps 2 keys in a dictionary to same value创建将字典中的 2 个键映射到相同值的数据框列
【发布时间】:2020-03-01 04:49:11
【问题描述】:

我有 2 个字典,想创建一个新列来将 2 个键映射到一个值。

字典 1

dict1 = 
{
    "A" :[619, 588],

    "B" : [772, 880],

    "C" : [033, 944],

    "D" : [077, 854]
}

字典 2

dict2 = 
{
    "A" : 600,

    "B" : 680,

    "C" : 300,

    "D" : 100
}

我想映射每个 ID,方法是创建一个新列“名称”,然后创建另一个将“名称”映射到值的列

ID   Name  Value
619   A     600
588   A     600
772   B     680
880   B     680
033   C     300
944   C     300
077   D     100
854   D     100

【问题讨论】:

    标签: python pandas dataframe dictionary hashmap


    【解决方案1】:

    使用DataFrame.melt + Series.map:

    df1=pd.DataFrame(dict1)
    df1_melt=df1.melt(var_name='Name',value_name='ID')
    df1_melt['value']=df1_melt.Name.map(dict2)
    #df1_melt=df1_melt.set_index('ID') #If you want ID like index 
    print(df1_melt)
    

    输出

      Name   ID  value
    0    A  619    600
    1    A  588    600
    2    B  772    680
    3    B  880    680
    4    C  033    300
    5    C  944    300
    6    D  077    100
    7    D  854    100
    

    注意字典1(dict1)中C和D的值必须作为字符串读取,因为它们都是以0开头的

    dict1 = 
    {
        "A" :[619, 588],
    
        "B" : [772, 880],
    
        "C" : ['033', '944'],
    
        "D" : ['077', '854']
    }
    

    【讨论】:

      【解决方案2】:

      如果您将第一个 dict 重新排列为更可行的格式,那么问题就会变得更加简单。

      id_mapper = {x: key for key, value in dict1.items() for x in value}
      
      df = pd.DataFrame(index = [
          "619",
          "588",
          "772",
          "880",
          "033",
          "944",
          "077",
          "854",
      ])
      
      df['Name'] = df.index.map(id_mapper)
      df['Value'] = df['Name'].map(dict2)
      
      >>> df
      
          ID      Name    Value
      0   619     A       600
      1   588     A       600
      2   772     B       680
      3   880     B       680
      4   033     C       300
      5   944     C       300
      6   077     D       100
      7   854     D       100
      

      为清楚起见,id_mapper 如下所示:

      {'619': 'A', '588': 'A', '772': 'B', ...}
      

      【讨论】:

        【解决方案3】:

        使用列表推导和构造函数。


        pd.DataFrame([
            dict(ID=el, Name=k, Value=dict2.get(k))
            for k, v in dict1.items()
            for el in v
        ])
        

            ID Name  Value
        0  619    A    600
        1  588    A    600
        2  772    B    680
        3  880    B    680
        4   33    C    300
        5  944    C    300
        6   77    D    100
        7  854    D    100
        

        【讨论】:

        • 我想我最喜欢这个。当我尝试调整我的答案时,我越来越接近这个答案。
        • pd.DataFrame([(i, n, dict2[n]) for n, I in dict1.items() for i in I], columns=['ID', 'Name', 'Value'])
        • 是的,最后明确的列名更简洁!
        【解决方案4】:

        假设dict1 中的所有值都是唯一的:

        d = {v: k for k in dict1 for v in dict1[k]}
        df = pd.DataFrame({'ID': list(d.keys()), 'Name': list(d.values())})
        >>> df.assign(Value=df['Name'].map(dict2))
            ID Name  Value
        0  619    A    600
        1  588    A    600
        2  772    B    680
        3  880    B    680
        4  033    C    300
        5  944    C    300
        6  077    D    100
        7  854    D    100
        

        或者:

        d = {v: k for k in dict1 for v in dict1[k]}
        df = pd.DataFrame({
            'ID': list(d.keys()), 
            'Name': list(d.values()), 
            'Value': [dict2[val] for val in d.values()]})
        

        【讨论】:

        • @AmoghKatwe 你也应该考虑支持这个答案。
        【解决方案5】:

        toolz.dicttoolz.merge

        from toolz.dicttoolz import merge
        
        d1 = merge(map(dict.fromkeys, dict1.values(), dict1))
        s = pd.Series(d1).rename_axis('ID')
        pd.concat({'Name': s, 'Value': s.map(dict2)}, axis=1).reset_index()
        
            ID Name  Value
        0  619    A    600
        1  588    A    600
        2  772    B    680
        3  880    B    680
        4  033    C    300
        5  944    C    300
        6  077    D    100
        7  854    D    100
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-03
          • 2013-01-08
          • 2019-05-11
          • 1970-01-01
          • 1970-01-01
          • 2018-08-13
          • 2021-05-26
          • 2021-07-14
          相关资源
          最近更新 更多