【问题标题】:Pandas remap or replace based on dictionary, but dictionary value pairs are in a listPandas 基于字典重新映射或替换,但字典值对在列表中
【发布时间】:2021-10-14 12:31:58
【问题描述】:

我正在尝试根据字典中的值对映射或替换 Pandas 数据框中的值。值对在一个列表中,我想将这些项目拆分为它们自己的列。值对列表中始终只有两项。

独立示例

mydf = pd.DataFrame({"x": [1, 2, 3, 4], "cat": ["text1", "text3", "text1", "text4"]})

mydict = {
    "text1": ["a15", "b3"],
    "text2": ["a6", "b1"],
    "text3": ["a3", "b3"],
    "text4": ["a1", "b12"],
}

display(mydf)

想要的结果

努力

基于a similar question here,我尝试了以下方法:

new_map = {str(x): str(k) for k, v in mydict.items() for x in v}
mydf['left'] = mydf['cat']
mydf['left'].map(new_map)

这不起作用,它会返回:

我还尝试了以下方法 (based on this):

new_map = {str(x): str(k) for k, v in mydict.items() for x in v}
mydf['left'] = mydf.index.map(lambda x: new_map[x])

导致错误KeyError: 0

【问题讨论】:

    标签: python pandas dictionary


    【解决方案1】:

    从映射中创建一个单独的数据框,并通过连接或 concat 连接回原始数据框:

        mapped = (mydf.cat
                      .map(mydict)
                      .apply(pd.Series)
                      .set_axis(['left', 'right'], axis='columns'))
        
          left right
        0  a15    b3
        1   a3    b3
        2  a15    b3
        3   a1   b12
    

    加入主df

     mydf.join(mapped)
    
       x    cat left right
    0  1  text1  a15    b3
    1  2  text3   a3    b3
    2  3  text1  a15    b3
    3  4  text4   a1   b12
    

    您可以使用@HenryEcker 的此解决方案跳过上面的详细选项:

    mydf[['left', 'right']] = mydf.cat.map(mydict).apply(pd.Series)
    

    【讨论】:

    • 好像mydf[['left', 'right']] = mydf.cat.map(mydict).apply(pd.Series)也可以在这里工作。
    【解决方案2】:

    我们可以使用pd.DataFrame.from_dictmydict 直接转换为DataFrame,然后将join 转换为mydf

    mydf = mydf.join(
        pd.DataFrame.from_dict(mydict, orient='index', columns=['left', 'right']),
        on='cat'
    )
    

    mydf:

       x    cat left right
    0  1  text1  a15    b3
    1  2  text3   a3    b3
    2  3  text1  a15    b3
    3  4  text4   a1   b12
    

    【讨论】:

      【解决方案3】:

      您可以使用merge。利用将mydict 转换为数据框不需要太多的事实:

      mydf.merge(pd.DataFrame(mydict,
                              index=['left', 'right']).T,
                 left_on='cat',
                 right_index=True,
                 how='left', sort=False
                )
      

      输出:

         x    cat left right
      0  1  text1  a15    b3
      1  2  text3   a3    b3
      2  3  text1  a15    b3
      3  4  text4   a1   b12
      

      【讨论】:

        【解决方案4】:

        这可以通过合并来完成。

        • 将字典转换为列表
        • 通过猫键合并
        mylist = [[key,mydict[key][0],mydict[key][1]] for key in mydict]
        df2 = pd.DataFrame(mylist,columns=['cat','left','right'])
        df2
        
        df = pd.merge(mydf,df2,on='cat',how='left')
        
            x   cat     left    right
        0   1   text1   a15     b3
        1   2   text3   a3      b3
        2   3   text1   a15     b3
        3   4   text4   a1      b12
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-05
          • 1970-01-01
          • 2018-03-08
          • 2016-09-02
          • 2022-12-11
          • 1970-01-01
          相关资源
          最近更新 更多