【问题标题】:Alternative method to json_normalize that flattens lists within dictionariesjson_normalize 的替代方法,用于展平字典中的列表
【发布时间】:2021-05-07 16:15:17
【问题描述】:

我有一本字典,其中包含一个需要展平到 0 级的列表。

目前,我使用的是json_normalize,但是,经过几天的研究,我发现它不处理列表并将其保留在一列中。

是否有其他方法可以使字典和列表变平?或者是通过创建函数的唯一可能解决方案?

{ 
    "_id" : 1, 
    "active" : false,  
    "labelId" : [
        6422
    ],  
    "level" : [
        {
            "active" : true, 
            "level" : 3, 
            "actions" : [
                {
                    "active" : true, 
                    "description" : "Testing."
                }
            ]
          } 
       ]
  }

电流输出:

预期输出:

【问题讨论】:

    标签: python json pandas dictionary


    【解决方案1】:

    您可以使用 json_normalise() explode()apply(pd.Series) 系统地分解它

    js = {'_id': 1,
     'active': False,
     'labelId': [6422],
     'level': [{'active': True,
       'level': 3,
       'actions': [{'active': True, 'description': 'Testing.'}]}]}
    
    df = pd.json_normalize(js).explode("labelId").explode("level")
    df = df.join(df["level"].apply(pd.Series), rsuffix="_l2").explode("actions")
    df = df.join(df["actions"].apply(pd.Series), rsuffix="_l3")
    print(df.drop(columns=["level","actions"]).to_string())
    

    输出

       _id  active labelId  active_l2  level_l2  active_l3 description
    0    1   False    6422       True         3       True    Testing.
    

    重命名前缀

    js = {'_id': 1,
     'active': False,
     'labelId': [6422],
     'level': [{'active': True,
       'level': 3,
       'actions': [{'active': True, 'description': 'Testing.'}]}]}
    
    df = pd.json_normalize(js).explode("labelId").explode("level")
    df = df.join(df["level"].apply(pd.Series), rsuffix="_l2").explode("actions")
    df = df.join(df["actions"].apply(pd.Series), rsuffix="_l3")
    df = df.drop(columns=["level","actions"])
    df.rename(columns={c:f"{c.split('_')[1]}_{c.split('_')[0]}" for c in df.columns if "_" in c})
    

    【讨论】:

    • 好主意,因为爆炸会为多条记录创建重复项,您的代码可以是df.drop_duplicates()subset = ["_id"], inplace = True,后跟一个简单的print(df)。我使用了这种方法,它非常适合我。
    • 我觉得奇怪的是数据结构有labelId作为一个列表...做两个explode()会产生奇怪的结果。 print() 只是我懒得将输出粘贴回 SO
    • 前缀是否有等价物,所以 rsuffix 是前缀,因为我需要将文本放在列名之前?例如_12level
    • 不...但您始终可以通过重命名列来实现这一点。更新以演示
    猜你喜欢
    • 2021-12-11
    • 2021-09-19
    • 2020-08-21
    • 2019-11-15
    • 2019-06-10
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    相关资源
    最近更新 更多