【问题标题】:convert dataframe to nested dictionary (one nesting level per column)将数据框转换为嵌套字典(每列一个嵌套级别)
【发布时间】:2022-01-13 12:37:47
【问题描述】:

我有这个数据框:

COL0    COL1    COL2    COL3
----------------------------
   A      A1     A11    A111
   A      A1     A11    A112
   A      A1     A12    A113
   A      A1     A12    A114
   A      A2     A13    A115
   A      A2     A13    A116
   A      A2     A14    A117
   A      A2     A14    A118

我想从中获得一个像下面这样的字典。如果我只是将 to_dict() 方法应用于原始数据帧,则格式不是我想要的。

{
    'A':{
        'A1':{
            'A11':['A111', 'A112'],
            'A12':['A113', 'A114']
        },
        'A2':{
            'A13':['A115', 'A116'],
            'A13':['A117', 'A118']            
        }
    }
}

PS:sn -p 生成上面的dataframe:

df = pd.DataFrame(
{
    'COL0': ['A']*8,
    'COL1': ['A1']*4 + ['A2']*4,
    'COL2': ['A11']*2 + ['A12']*2 + ['A12']*2 + ['A13']*2,
    'COL3': [f'A11{i+1}' for i in range(8)]
})

编辑:

TypeError Traceback(最近调用 最后)在 1 {a: {k: f.groupby('COL2')['COL3'].apply(list).to_dict() 2 for k, f in g.groupby('COL1')} ----> 3 for a, g in df.groupby('COL0')}

在 (.0) 1 {a: {k: f.groupby('COL2')['COL3'].apply(list).to_dict() 2 for k, f in g.groupby('COL1')} ----> 3 for a, g in df.groupby('COL0')}

在 (.0) 1 {a: {k: f.groupby('COL2')['COL3'].apply(list).to_dict() ----> 2 for k, f in g.groupby('COL1')} 3 for a, g in df.groupby('COL0')}

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\groupby\generic.py 在应用(自我,函数,*args,**kwargs) 219) 220 def 应用(自我,函数,*args,**kwargs): --> 221 返回 super().apply(func, *args, **kwargs) 222 223 @doc(_agg_template,示例=_agg_examples_doc,klass =“系列”)

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\groupby\groupby.py 在应用(自我,函数,*args,**kwargs) 第865章 866 --> 867 函数 = self._is_builtin_func(func) 868 869 # 这是必需的,所以我们不会尝试包装字符串。如果我们可以

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\base.py 在 _is_builtin_func(self, arg) 342 否则返回 arg 第343章 --> 344 返回 self._builtin_table.get(arg, arg) 345 346

TypeError: unhashable type: 'list'

EDIT2:

TypeError Traceback(最近调用 最后)在 1 出 = {} ----> 2 键,v in df.groupby(list(df.columns[:-1]))[df.columns[-1]]: 3 d = out # 从根目录重启 4 val = v.to_list() 5 代表 k 键:

TypeError: 'list' 对象不可调用

【问题讨论】:

    标签: python pandas dataframe dictionary


    【解决方案1】:

    遍历行并收集键值对;如果键不存在,使用dict.setdefault 设置默认值:

    out = {}
    for w,x,y,z in df.to_numpy():
        out.setdefault(w, {}).setdefault(x, {}).setdefault(y, []).append(z)
    

    使用 pd.groupby 和嵌套的 dict 理解:

    out = {a: {k: f.groupby('COL2')['COL3'].apply(list).to_dict()
               for k, f in g.groupby('COL1')} 
           for a, g in df.groupby('COL0')}
    

    输出:

    {'A': {'A1': {'A11': ['A111', 'A112'], 'A12': ['A113', 'A114']},
      'A2': {'A13': ['A115', 'A116'], 'A14': ['A117', 'A118']}}}
    

    【讨论】:

    • pandas.groupby 有办法吗?
    • 它抛出:TypeError: unhashable type: 'list'
    • @JaviTorre setdefault 解决方案有效吗?
    【解决方案2】:

    这是一种适用于任意数量列的方法。

    它使用第一个 groupby 来设置除最后一列之外的所有组。

    然后它沿着树向下移动,更改对父级的引用,直到到达最后一个键。

    out = {}
    for keys, v in df.groupby(list(df.columns[:-1]))[df.columns[-1]]:
        d = out             # restart at root
        val = v.to_list()
        for k in keys:
            if k not in d:
                d[k] = {}   # create child if missing
            parent = d
            d = d[k]        # go down in nested level
        parent[k] = val     # we reached the bottom, set the value
    

    输出:

    {'A': {'A1': {'A11': ['A111', 'A112'],
                  'A12': ['A113', 'A114']},
           'A2': {'A13': ['A115', 'A116'],
                  'A14': ['A117', 'A118']},
           },
    }
    

    进一步嵌套字典的示例:

    from  itertools import product
    df = (pd.DataFrame(product('AB', '12', '123', '1', '12'))
            .add_prefix('COL').cumsum(1)
          )
    #    COL0 COL1 COL2  COL3   COL4
    #  0    A   A1  A11  A111  A1111
    #  1    A   A1  A11  A111  A1112
    #  2    A   A1  A12  A121  A1211
    #  3    A   A1  A12  A121  A1212
    #  4    A   A1  A13  A131  A1311
    # ...
    # 23    B   B2  B23  B231  B2312
    

    输出:

    {'A': {'A1': {'A11': {'A111': ['A1111', 'A1112']},
                  'A12': {'A121': ['A1211', 'A1212']},
                  'A13': {'A131': ['A1311', 'A1312']}},
           'A2': {'A21': {'A211': ['A2111', 'A2112']},
                  'A22': {'A221': ['A2211', 'A2212']},
                  'A23': {'A231': ['A2311', 'A2312']}}},
     'B': {'B1': {'B11': {'B111': ['B1111', 'B1112']},
                  'B12': {'B121': ['B1211', 'B1212']},
                  'B13': {'B131': ['B1311', 'B1312']}},
           'B2': {'B21': {'B211': ['B2111', 'B2112']},
                  'B22': {'B221': ['B2211', 'B2212']},
                  'B23': {'B231': ['B2311', 'B2312']}}}}
    

    【讨论】:

    • 它抛出 TypeError: 'list' object is not callable 你使用的是什么 python 版本?
    • python 3 ;你能提供完整的错误回溯吗?
    • 请在我的编辑中查看。
    • @Javi 这不是我的代码,请试试我的 ;)
    • 道歉,见edit2
    猜你喜欢
    • 2018-08-14
    • 2014-05-10
    • 1970-01-01
    • 2020-09-03
    • 2020-07-31
    • 2021-11-28
    • 2022-01-07
    • 1970-01-01
    相关资源
    最近更新 更多