【问题标题】:pandas dataframe as nested json熊猫数据框作为嵌套的 json
【发布时间】:2019-06-06 07:14:56
【问题描述】:

我有一个脚本,它将嵌套的 JSON 读取为 pandas 数据框,并向其中添加一个新列并将其另存为 JSON。

import numpy as np
from pandas.io.json import json_normalize

sample_json = {
    "name": {
        "emails": [{"address": "clark.kent@example.com"}],
        "countries": [{"country": "US"}, {"country": "UK"}],
    }
}
df = json_normalize(sample_json)

df["name.hobbies"] = np.nan

print(df)

df.to_json("sample.json", orient="records", lines=True)

我的输出看起来像,

{
    "name.countries": [
        {
            "country": "US"
        },
        {
            "country": "UK"
        }
    ],
    "name.emails": [
        {
            "address": "clark.kent@example.com"
        }
    ],
    "name.hobbies": null
}

我想将数据框保存为嵌套的 JSON,就像这样,

"name": {
        "emails": [{"address": "clark.kent@example.com"}],
        "countries": [{"country": "US"}, {"country": "UK"}],
        "hobbies": null
    }

有没有办法将派生自的 pandas 数据帧保存为嵌套 JSON?

【问题讨论】:

    标签: python json pandas


    【解决方案1】:

    在我看来,嵌套 json 是最简单的创建字典,添加新值并最后转换为 json:

    sample_json['name']['hobies'] = None
    
    j = json.dumps(sample_json)
    print (j)
    {"name": {"emails": [{"address": "clark.kent@example.com"}], 
              "countries": [{"country": "US"}, {"country": "UK"}],
              "hobies": null}}
    

    Pandas 解决方案 - 通过拆分列名创建 MultiIndex 并创建嵌套字典:

    df.columns = df.columns.str.split('.', expand=True)
    d = {level: df.xs(level, axis=1).squeeze().to_dict() for level in df.columns.levels[0]}
    print (d)
    
    {'name': {'countries': [{'country': 'US'}, {'country': 'UK'}], 
              'emails': [{'address': 'clark.kent@example.com'}], 
              'hobbies': nan}}
    

    对于将NaNs 转换为nulls 检查Python NaN JSON encoder,最简单的是设置None 而不是NaNs 或用Nones 替换缺失值:

    df = df.where(df.notna(), None)
    df.columns = df.columns.str.split('.', expand=True)
    d = {level: df.xs(level, axis=1).squeeze().to_dict() for level in df.columns.levels[0]}
    
    j = json.dumps(d)
    print (j)
    {"name": {"countries": [{"country": "US"}, {"country": "UK"}],
              "emails": [{"address": "clark.kent@example.com"}],
              "hobbies": null}}
    

    【讨论】:

    • 非常感谢。这适用于两个级别。我尝试了 4 个级别,但失败了。例如,如果我的列名是 'person.dob.date_range.start''person.dob.date_range.end''person.dob.display''person.educations''available_data.premium.dobs''available_data.premium.educations'
    • @akileshraj - 使用嵌套的 json 很痛苦,所以尝试创建这个结构并尝试找到解决方案。不过真的不容易……
    猜你喜欢
    • 1970-01-01
    • 2017-11-28
    • 2020-10-18
    • 2021-12-23
    • 2021-10-08
    • 2021-02-15
    • 2019-03-18
    • 2017-04-03
    相关资源
    最近更新 更多