【问题标题】:How to convert nested JSON data to CSV using python?如何使用 python 将嵌套的 JSON 数据转换为 CSV?
【发布时间】:2019-05-27 21:54:07
【问题描述】:

我有一个文件,该文件由一个包含 5000 多个对象的数组组成。但是,我无法将 JSON 文件的特定部分转换为 CSV 格式的相应列。

以下是我的数据文件的示例版本:

{
  "Result": {
    "Example 1": {
      "Type1": [
        {
          "Owner": "Name1 Example",
          "Description": "Description1 Example",
          "Email": "example1_email@email.com",
          "Phone": "(123) 456-7890"
        }
      ]
    },
    "Example 2": {
      "Type1": [
        {
          "Owner": "Name2 Example",
          "Description": "Description2 Example",
          "Email": "example2_email@email.com",
          "Phone": "(111) 222-3333"
        }
      ]
    }
  }
}

这是我当前的代码:

import csv
import json

json_file='example.json'
with open(json_file, 'r') as json_data:
    x = json.load(json_data)

f = csv.writer(open("example.csv", "w"))

f.writerow(["Address","Type","Owner","Description","Email","Phone"])

for key in x["Result"]:
    type = "Type1"
    f.writerow([key,
                type,
                x["Result"][key]["Type1"]["Owner"],
                x["Result"][key]["Type1"]["Description"],
                x["Result"][key]["Type1"]["Email"],
                x["Result"][key]["Type1"]["Phone"]])

我的问题是我遇到了这个问题:

Traceback (most recent call last):
  File "./convert.py", line 18, in <module>
    x["Result"][key]["Type1"]["Owner"],
TypeError: list indices must be integers or slices, not str

当我尝试将最后一个数组(例如“所有者”)替换为整数值时,我收到此错误:IndexError: list index out of range

当我将 f.writerow 函数严格更改为

f.writerow([key,
                type,
                x["Result"][key]["Type1"]])

我在一列中收到结果,但它将所有内容合并到一列中,这是有道理的。输出图片:https://imgur.com/a/JpDkaAT

我希望根据标签将结果分成单独的列,而不是合并为一列。有人可以帮忙吗?

谢谢!

【问题讨论】:

    标签: python json csv


    【解决方案1】:

    Type1 在你的数据结构中是一个列表,而不是一个字典。因此,您需要对其进行迭代,而不是按键引用。

    for key in x["Result"]:
        # key is now "Example 1" etc.
        type1 = x["Result"][key]["Type1"]
        # type1 is a list, not a dict
        for i in type1:
            f.writerow([key,
                        "Type1",
                        type1["Owner"],
                        type1["Description"],
                        type1["Email"],
                        type1["Phone"]])
    

    内部 for 循环确保您免受“Type1”在列表中只有一项的假设的保护。

    【讨论】:

    • 谢谢!我忘了考虑到列表中可能不止一项。
    【解决方案2】:

    这绝对不是最好的例子,但我很想优化它。

    import csv
    
    
    def json_to_csv(obj, res):
        for k, v in obj.items():
            if isinstance(v, dict):
                res.append(k)
                json_to_csv(v, res)
            elif isinstance(v, list):
                res.append(k)
                for el in v:
                    json_to_csv(el, res)
            else:
                res.append(v)
    
    
    obj = {
      "Result": {
        "Example 1": {
          "Type1": [
            {
              "Owner": "Name1 Example",
              "Description": "Description1 Example",
              "Email": "example1_email@email.com",
              "Phone": "(123) 456-7890"
            }
          ]
        },
        "Example 2": {
          "Type1": [
            {
              "Owner": "Name2 Example",
              "Description": "Description2 Example",
              "Email": "example2_email@email.com",
              "Phone": "(111) 222-3333"
            }
          ]
        }
      }
    }
    
    with open("out.csv", "w+") as f:
        writer = csv.writer(f)
        writer.writerow(["Address","Type","Owner","Description","Email","Phone"])
        for k, v in obj["Result"].items():
            row = [k]
            json_to_csv(v, row)
            writer.writerow(row)
    

    【讨论】:

      【解决方案3】:

      想通了!

      我将 f.writerow 函数更改为以下内容:

      for key in x["Result"]:
          type = "Type1"
          f.writerow([key,
                      type,
                      x["Result"][key]["Type1"][0]["Owner"],
                      x["Result"][key]["Type1"][0]["Email"]])
                      ...
      

      这允许我引用对象中的键。希望这可以帮助某人!

      【讨论】:

      • 如果“Type1”在列表中有多个条目怎么办?
      猜你喜欢
      • 2022-10-15
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 2020-01-16
      • 2018-10-27
      • 2021-05-17
      • 2017-06-10
      • 1970-01-01
      相关资源
      最近更新 更多