【问题标题】:Constructing a pandas DataFrame with columns and sub-columns from nested dictionary使用嵌套字典中的列和子列构建 pandas DataFrame
【发布时间】:2020-10-14 18:51:19
【问题描述】:

我有什么:

如下形式的嵌套字典a

    a={
   "level1": {
           "t1":{
                   "s1":{
                           "col1":5,
                           "col2":4,
                           "col3":4,
                           "col4":9
                           
                        },
                   "s2":{
                           "col1":1,
                           "col2":5,
                           "col3":4,
                           "col4":8
                           
                        },
                   "s3":{
                           "col1":11,
                           "col2":8,
                           "col3":2,
                           "col4":9
                           
                        },
                   "s4":{
                           "col1":5,
                           "col2":4,
                           "col3":4,
                           "col4":9
                           
                        }
                   
                },
           "t2":{
                   "s1":{
                           "col1":5,
                           "col2":4,
                           "col3":4,
                           "col4":9
                           
                        },
                   "s2":{
                           "col1":1,
                           "col2":5,
                           "col3":4,
                           "col4":8
                           
                        },
                   "s3":{
                           "col1":11,
                           "col2":8,
                           "col3":2,
                           "col4":9
                           
                        },
                   "s4":{
                           "col1":5,
                           "col2":4,
                           "col3":4,
                           "col4":9
                           
                        }
                   
                },
           
           "t3":{
                   "s1":{
                           "col1":1,
                           "col2":2,
                           "col3":3,
                           "col4":4
                           
                        },
                   "s2":{
                           "col1":5,
                           "col2":6,
                           "col3":7,
                           "col4":8
                           
                        },
                   "s3":{
                           "col1":9,
                           "col2":10,
                           "col3":11,
                           "col4":12
                           
                        },
                   "s4":{
                           "col1":13,
                           "col2":14,
                           "col3":15,
                           "col4":16
                           
                        }
                   
                }
              
        },
   
   "level2": {
           "t1":{
                   "s1":{
                           "col1":5,
                           "col2":4,
                           "col3":9,
                           "col4":9
                           
                        },
                   "s2":{
                           "col1":1,
                           "col2":5,
                           "col3":4,
                           "col4":5
                           
                        },
                   "s3":{
                           "col1":11,
                           "col2":8,
                           "col3":2,
                           "col4":13
                           
                        },
                   "s4":{
                           "col1":5,
                           "col2":4,
                           "col3":4,
                           "col4":20
                           
                        }
                   
                },
           "t2":{
                   "s1":{
                           "col1":5,
                           "col2":4,
                           "col3":4,
                           "col4":9
                           
                        },
                   "s2":{
                           "col1":1,
                           "col2":5,
                           "col3":4,
                           "col4":8
                           
                        },
                   "s3":{
                           "col1":11,
                           "col2":8,
                           "col3":2,
                           "col4":9
                           
                        },
                   "s4":{
                           "col1":5,
                           "col2":4,
                           "col3":4,
                           "col4":9
                           
                        }
                   
                },
           
           "t3":{
                   "s1":{
                           "col1":1,
                           "col2":2,
                           "col3":3,
                           "col4":4
                           
                        },
                   "s2":{
                           "col1":5,
                           "col2":6,
                           "col3":7,
                           "col4":8
                           
                        },
                   "s3":{
                           "col1":9,
                           "col2":10,
                           "col3":11,
                           "col4":12
                           
                        },
                   "s4":{
                           "col1":13,
                           "col2":14,
                           "col3":15,
                           "col4":16
                           
                        }
                   
                }
              
        }
  }

即标记为"level"的键是a的主键,标记为"t"的键是每个"level"中嵌套字典的键,最后标记为"s"的键。现在,对应于每个标记为 "s" 的键,有一个字典,其中包含四个键 "col1","col2", "col3""col4" 实际数据所在的位置。

目标:

我想通过以下方式从a 构造一个熊猫数据框:

Nested Dictionary into the dataframe

也就是说,我希望 "level""t" 键分别用作数据帧的主索引和辅助索引,而 "s""col" 键分别用作此的主列和辅助列数据框。

到目前为止我尝试过的方法:

我尝试使用pandas.DataFrame.from_dictpandas.json_normalize 方法。已经有一个类似问题的解决方案,它使用pandas.DataFrame.from_dict,但我没有从中得到太多帮助,因为它使用a 中的"s" 键作为索引而不是数据框中的主列,并且我无法理解 pandas.json_normalize 的工作原理,因此无法获得预期的结果

pandas 有什么函数可以直接实现吗?另外,我不知道 pandas 数据框是否支持这种类型的列。

我在 Python 3.8.3 上使用 pandas 版本 1.0.5。任何帮助表示赞赏。提前谢谢你

【问题讨论】:

    标签: python-3.x pandas dataframe dictionary


    【解决方案1】:

    您可以使用基础 pd.json_normalize 将数据加载到 1 个非常宽的数据帧中。从那里您需要将您的列转换为pd.MultiIndex,然后您可以根据需要堆叠您的级别。这对我有用:

    读取数据:

    df = pd.json_normalize(a)
    
    # Print first 4 columns because dataframe is SUPER wide
    print(df.iloc[:, :4])
       level1.t1.s1.col1  level1.t1.s1.col2  level1.t1.s1.col3  level1.t1.s1.col4
    0                  5                  4                  4                  9
    

    现在我们需要通过分隔“.”上的每个列名来将我们的列转换为pd.MultiIndex

    # Splitting the by "." returns an index of list objects. By using 
    #  map(tuple) we change the nested lists into nested tuples
    #  pandas detects the tuples and automatically creates a MultiIndex
    df.columns = df.columns.str.split(".").map(tuple)
    
    # Print first 8 columns because dataframe is still fairly wide
    print(df.iloc[:, :8])
      level1                                   
          t1                                   
          s1                  s2               
        col1 col2 col3 col4 col1 col2 col3 col4
    0      5    4    4    9    1    5    4    8
    

    现在我们可以堆叠我们列的前 2 层以将它们变成行索引:

    # stack the first 2 levels [0, 1]
    #  reset_index() to get rid of the outer level of the index since it isn't meaningful
    out = df.stack([0, 1]).reset_index(0, drop=True)
    
    print(out)
                s1                  s2                  s3                  s4               
              col1 col2 col3 col4 col1 col2 col3 col4 col1 col2 col3 col4 col1 col2 col3 col4
    level1 t1    5    4    4    9    1    5    4    8   11    8    2    9    5    4    4    9
           t2    5    4    4    9    1    5    4    8   11    8    2    9    5    4    4    9
           t3    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16
    level2 t1    5    4    9    9    1    5    4    5   11    8    2   13    5    4    4   20
           t2    5    4    4    9    1    5    4    8   11    8    2    9    5    4    4    9
           t3    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16
    

    【讨论】:

    • 效果很好!然而,我注意到在进行堆栈操作时,pandas 会按字母顺序重新排序。有没有办法做同样的事情,但保持原来的顺序(比如如果使用 OrderedDict)?
    猜你喜欢
    • 2016-07-24
    • 2017-12-26
    • 2019-07-26
    • 2019-06-27
    • 2018-05-05
    • 2023-04-02
    • 2018-11-01
    • 2021-06-09
    • 2018-10-26
    相关资源
    最近更新 更多