【问题标题】:How to create a new column in a dataframe using a multikey dictionary如何使用多键字典在数据框中创建新列
【发布时间】:2020-01-29 12:02:52
【问题描述】:

我有一个多键字典,我想用它在数据框中创建一个新列。使用单个关键数据帧这样做非常容易,但我很难理解将两个值发送到字典的正确语法是什么。

我已经能够通过 map、get 和 apply 使用单键字典(map 示例)

    import pandas as pd      
    df = pd.DataFrame(data = {'Col1': [1, 2, 3, 4], 'Col2': ['A', 'B', 'C', 'D']})

    single_dict = {1: 'This', 2: 'is', 3: 'pretty', 4: 'easy'}

    df['newcol_a'] = df['Col1'].map(single_dict)

    print(df)```

返回预期的"

    Col1 Col2 newcol_a
    0     1    A     This
    1     2    B       is
    2     3    C   pretty
    3     4    D     easy

但是当我创建一个多键字典时,例如

dbl_dict = {1: {'A': 'THIS', 'B': 'blah', 'C': 'blah', 'D': 'blah'},
            2: {'A': 'blah', 'B': 'HAS' , 'C': 'blah', 'D': 'blah'},
            3: {'A': 'blah', 'B': 'blah', 'C': 'ME'  , 'D': 'blah'},
            4: {'A': 'blah', 'B': 'blah', 'C': 'blah', 'D': 'STUMPED'},}

我可以使用'get'来调用它

dbl_dict.get(1, {}).get('A', 'Other')
Out[5]: 'THIS'      

但我无法弄清楚获得所需结果的语法(尝试了大约 40 种不同的东西,例如 df['newcol_b'] = df[['Col1', 'Col2']].map(dbl_dict) ):

    Col1 Col2 newcol_a
    0     1    A     THIS
    1     2    B      HAS
    2     3    C       ME
    3     4    D  STUMPED

【问题讨论】:

    标签: python dataframe dictionary multikey


    【解决方案1】:

    map 不知道如何处理嵌套字典。如果你坚持使用这个字典,你可以在整个数据框上使用apply,但你必须创建一个自定义映射函数:

    import pandas as pd
    
    df = pd.DataFrame(data={'Col1': [1, 2, 3, 4], 'Col2': ['A', 'B', 'C', 'D']})
    dbl_dict = {1: {'A': 'THIS', 'B': 'blah', 'C': 'blah', 'D': 'blah'},
                2: {'A': 'blah', 'B': 'HAS', 'C': 'blah', 'D': 'blah'},
                3: {'A': 'blah', 'B': 'blah', 'C': 'ME', 'D': 'blah'},
                4: {'A': 'blah', 'B': 'blah', 'C': 'blah', 'D': 'STUMPED'}}
    
    df['new_col'] = df.apply(lambda s: dbl_dict.get(s['Col1'], {}).get(s['Col2']), axis=1)
    

    df 现在是

       Col1 Col2  new_col
    0     1    A     THIS
    1     2    B      HAS
    2     3    C       ME
    3     4    D  STUMPED
    

    loc(或at)的解决方案可能是可能的(如果是这样,可能会更快)。需要调查一下。

    【讨论】:

    • 谢谢,这肯定会让代码运行。但是你的评论“如果你坚持使用这个字典”让我问,你会推荐一种不同的方法吗?我正在处理的数据需要根据 2 或 3 列的值有条件地对数据进行分组,以进行分析和报告。您还有其他建议吗?我应该补充一点,我的背景是 SAS,通常 SAS 中最好的工具是 Format 函数——它类似于字典以及我最终采用这种方法的方式。再次感谢。
    【解决方案2】:

    在我看来,最简单的选择是使用嵌套字典创建一个新的 DataFrame 并取消堆叠此 DataFrame,然后您可以将其与原始 DataFrame 加入,如下所示:

    s = pd.DataFrame(dbl_dict).unstack().rename_axis(('Col1','Col2')).rename('new_column')
    print (s)
    df = df.join(s, on=['Col1','Col2'])
    print (df)
    

    【讨论】:

      【解决方案3】:

      我创建了一个很小的(2 行)自定义函数供您使用,它似乎可以解决此问题。当然,这可以改进以捕获特定情况下的一些错误和行为。

      import pandas as pd
      data = {'col_1':[1,2,3,4],'col_2':['A','B','C','D']}
      df = pd.DataFrame(data)
      dbl_dict = {1: {'A': 'THIS', 'B': 'blah', 'C': 'blah', 'D': 'blah'},
                  2: {'A': 'blah', 'B': 'HAS' , 'C': 'blah', 'D': 'blah'},
                  3: {'A': 'blah', 'B': 'blah', 'C': 'ME'  , 'D': 'blah'},
                  4: {'A': 'blah', 'B': 'blah', 'C': 'blah', 'D': 'STUMPED'},}
      def maperino(dict_name,key_1,key_2):
          val = [dict_name[key_1[i]][key_2[i]] for i in range(len(key_1))]
          return val        
      df['col_3'] = maperino(dbl_dict,df['col_1'],df['col_2'])
      print(df)
      

      输出:

         col_1 col_2    col_3
      0      1     A     THIS
      1      2     B      HAS
      2      3     C       ME
      3      4     D  STUMPED
      

      【讨论】:

      • 没有投反对票,但为什么for 循环?你已经有一个字典
      • 我想从函数中返回一个列表,以便稍后作为系列传递到新列中。当然,您的解决方案更好,但我需要返回一个列表来创建我相信的新列。 (也为您 +1 方便使用 lambda 来避免该功能)。
      猜你喜欢
      • 2021-09-22
      • 2022-06-22
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      • 2020-11-12
      • 2021-08-18
      • 2018-05-08
      相关资源
      最近更新 更多