Как преобразовать вложенные данные JSON в CSV с помощью python?

У меня есть файл, состоящий из массива, содержащего более 5000 объектов. Однако у меня возникли проблемы с преобразованием одной конкретной части моего файла JSON в соответствующие столбцы в формате CSV.

Ниже приведен пример версии моего файла данных:

{
  "Result": {
    "Example 1": {
      "Type1": [
        {
          "Owner": "Name1 Example",
          "Description": "Description1 Example",
          "Email": "[email protected]",
          "Phone": "(123) 456-7890"
        }
      ]
    },
    "Example 2": {
      "Type1": [
        {
          "Owner": "Name2 Example",
          "Description": "Description2 Example",
          "Email": "[email protected]",
          "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([key,
                type,
                x["Result"][key]["Type1"]])

Я получаю результаты в столбце, но он объединяет все в один столбец, что имеет смысл. Изображение выхода: https://imgur.com/a/JpDkaAT

Я хотел бы, чтобы результаты были разделены на основе метки на отдельные столбцы, а не объединены в один. Может ли кто-нибудь помочь?

Спасибо!

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
237
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это определенно не лучший пример, но я слишком сонный, чтобы его оптимизировать.

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": "[email protected]",
          "Phone": "(123) 456-7890"
        }
      ]
    },
    "Example 2": {
      "Type1": [
        {
          "Owner": "Name2 Example",
          "Description": "Description2 Example",
          "Email": "[email protected]",
          "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)

Догадаться!

Я изменил функцию ф.пистероу на следующую:

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

Это позволило мне ссылаться на ключи внутри объекта. Надеюсь, это поможет кому-то в будущем!

Что делать, если «Тип1» имеет более одной записи в списке?

Will 28.05.2019 00:19
Ответ принят как подходящий

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» имеет только один элемент в списке.

Спасибо! Я забыл принять во внимание, что в списке может быть более одного элемента.

hchong 28.05.2019 00:23

Другие вопросы по теме