【问题标题】:Converting a JSON with a nested array to CSV将带有嵌套数组的 JSON 转换为 CSV
【发布时间】:2019-03-16 08:02:54
【问题描述】:

这是我的 JSON 模板:

{
  "field 1": [
    {
      "id": "123456"
    },
    {
      "about": "YESH"
    },
    {
      "can_post": true
    },
    {
      "category": "Community"
    }
  ],
  "field 2": [
    {
      "id": "123456"
    },
    {
      "about": "YESH"
    },
    {
      "can_post": true
    },
    {
      "category": "Community"
    }
  ]
}

我想使用 Python 将此 JSON 转换为以下格式的 csv:

0 field 1, id, about, can_post, category

1 field 2, id, about, can_post, category

我尝试使用 pandas 读取_json,然后读取 to_csv,但没有成功。

谢谢

【问题讨论】:

  • 我不明白你为什么使用数组作为键field1

标签: python json csv


【解决方案1】:
import csv
import json

json.load(json_data) 将json_data(json文档(txt/二进制文件))反序列化为python对象。

with open('jsn.txt','r') as json_data:
    json_dict = json.load(json_data)

由于您的字段名称(将充当字段名称的键)位于不同的字典中,我们必须检查这些字典并将它们放入列表field_names

field_names = [ 'field']
for d in json_dict['field 1']:
    field_names.extend(d.keys())

with open('mycsvfile.csv', 'w') as f:  
    w = csv.DictWriter(f, fieldnames = fieild_names)
    w.writeheader()

    for k1, arr_v in json_dict.items():
        temp = {k2:v for d in arr_v for k2,v in d.items()}
        temp['field'] = k1
        w.writerow(temp)


输出

field,id,about,can_post,category
field 1,123456,YESH,True,Community
field 2,123456,YESH,True,Community


如果您发现上述 dict 理解令人困惑

      k1  : arr_v 
'field 1' = [{ "id": "123456" },...{"category": "Community"}]

            for d in arr_v:                 
                        k2 : v
               d --> { "id": "123456" }

【讨论】:

    【解决方案2】:

    这个怎么样,如果你有像data这样的json

    data = [
       {
        "site": "field1",
        "id": "123456",
        "about": "YESH",
        "can_post": True,
        "category": "Community"
      },
      {
        "site": "field2",
        "id": "123456",
        "about": "YESH",
        "can_post": True,
        "category": "Community"
      }
    ]
    # also use True instead of true
    
    df = pd.DataFrame.from_dict(data)
    
    print(df)
    # use df.to_csv('filename.csv') for csv
    

    输出:

      about  can_post   category      id    site
    0  YESH      True  Community  123456  field1
    1  YESH      True  Community  123456  field2
    

    【讨论】:

    • 这是我的结果:字段 1 字段 2 0 {u'id': u'123456'} {u'id': u'123456'} 1 {u'about': u'YESH '} {u'about': u'YESH'} 2 {u'can_post': True} {u'can_post': True} 3 {u'category': u'Community'} {u'category': u'社区'}
    【解决方案3】:

    这里的难点在于你的 json 初始结构不仅仅是一个映射列表,而是一个映射,其中值依次是映射列表。

    恕我直言,您必须对输入进行预处理,或逐个元素处理它以获取可以转换为 csv 行的列表或映射。这是一个可能的解决方案:

    • 提取第一个元素的键并使用它们构建 DictWriter
    • 为每个元素构建一个映射并将其存储在 DictWriter 中

    代码可以是:

    import json
    import csv
    
    # read the json data
    with open("input.json") as fd:
        data = json.load(fd)
    
    # extract the field names (using 'field' for the key):
    names = ['field']
    for d in next(iter(data.values())):
        names.extend(d.keys())
    
    # open the csv file as a DictWriter using those names
    with open("output.csv", "w", newline='') as fd:
        wr = csv.DictWriter(fd, names)
        wr.writeheader()
        for field, vals in data.items():
            d['field'] = field
            for inner in vals:
                for k,v in inner.items():
                    d[k] = v
            wr.writerow(d)
    

    它给出的数据是:

    field,id,about,can_post,category
    field 1,123456,YESH,True,Community
    field 2,123456,YESH,True,Community
    

    【讨论】:

    • 我收到以下错误:“names.extend(d.key()) AttributeError: ‘dict’ object has no attribute ‘key’”
    • @GuyShoshan:不确定是否是拼写错误,但我写的是 keys,而不是你在评论中所做的 key
    猜你喜欢
    • 2020-12-29
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2022-01-07
    • 2018-01-07
    • 2020-10-28
    • 1970-01-01
    相关资源
    最近更新 更多