Вопрос-Ответ

How can I convert JSON to CSV?

Как я могу преобразовать JSON в CSV?

У меня есть файл JSON, который я хочу преобразовать в файл CSV. Как я могу это сделать с помощью Python?

Я пробовал:

import json
import csv

f = open('data.json')
data = json.load(f)
f.close()

f = open('data.csv')
csv_file = csv.writer(f)
for item in data:
csv_file.writerow(item)

f.close()

Однако это не сработало. Я использую Django, и я получил ошибку:

`file' object has no attribute 'writerow'`

Затем я попробовал следующее:

import json
import csv

f = open('data.json')
data = json.load(f)
f.close()

f = open('data.csv')
csv_file = csv.writer(f)
for item in data:
f.writerow(item) # ← changed

f.close()

Затем я получаю сообщение об ошибке:

`sequence expected`

Пример файла json:

[{
"pk": 22,
"model": "auth.permission",
"fields": {
"codename": "add_logentry",
"name": "Can add log entry",
"content_type": 8
}
}, {
"pk": 23,
"model": "auth.permission",
"fields": {
"codename": "change_logentry",
"name": "Can change log entry",
"content_type": 8
}
}, {
"pk": 24,
"model": "auth.permission",
"fields": {
"codename": "delete_logentry",
"name": "Can delete log entry",
"content_type": 8
}
}, {
"pk": 4,
"model": "auth.permission",
"fields": {
"codename": "add_group",
"name": "Can add group",
"content_type": 2
}
}, {
"pk": 10,
"model": "auth.permission",
"fields": {
"codename": "add_message",
"name": "Can add message",
"content_type": 4
}
}
]
Переведено автоматически
Ответ 1

С pandas библиотекой это так же просто, как использовать две команды!

df = pd.read_json()

read_json преобразует строку JSON в объект pandas (либо серию, либо фрейм данных). Затем:

df.to_csv()

Который может либо возвращать строку, либо записывать непосредственно в csv-файл. Смотрите документацию для to_csv.

Основываясь на подробностях предыдущих ответов, мы все должны поблагодарить pandas за короткий путь.

Неструктурированный JSON смотрите в этом ответе.

РЕДАКТИРОВАТЬ: кто-то попросил рабочий минимальный пример:

import pandas as pd

with open('jsonfile.json', encoding='utf-8') as inputfile:
df = pd.read_json(inputfile)

df.to_csv('csvfile.csv', encoding='utf-8', index=False)
Ответ 2

Во-первых, ваш JSON содержит вложенные объекты, поэтому обычно его нельзя преобразовать напрямую в CSV. Вам нужно изменить это на что-то вроде этого:

{
"pk": 22,
"model": "auth.permission",
"codename": "add_logentry",
"content_type": 8,
"name": "Can add log entry"
},
......]

Вот мой код для генерации CSV из этого:

import csv
import json

x = """[
{
"pk": 22,
"model": "auth.permission",
"fields": {
"codename": "add_logentry",
"name": "Can add log entry",
"content_type": 8
}
},
{
"pk": 23,
"model": "auth.permission",
"fields": {
"codename": "change_logentry",
"name": "Can change log entry",
"content_type": 8
}
},
{
"pk": 24,
"model": "auth.permission",
"fields": {
"codename": "delete_logentry",
"name": "Can delete log entry",
"content_type": 8
}
}
]"""


x = json.loads(x)

f = csv.writer(open("test.csv", "wb+"))

# Write CSV Header, If you dont need that, remove this line
f.writerow(["pk", "model", "codename", "name", "content_type"])

for x in x:
f.writerow([x["pk"],
x["model"],
x["fields"]["codename"],
x["fields"]["name"],
x["fields"]["content_type"]])

Вы получите вывод в виде:

pk,model,codename,name,content_type
22,auth.permission,add_logentry,Can add log entry,8
23,auth.permission,change_logentry,Can change log entry,8
24,auth.permission,delete_logentry,Can delete log entry,8
Ответ 3

Я предполагаю, что ваш файл JSON будет декодирован в список словарей. Сначала нам нужна функция, которая сгладит объекты JSON:

def flattenjson(b, delim):
val = {}
for i in b.keys():
if isinstance(b[i], dict):
get = flattenjson(b[i], delim)
for j in get.keys():
val[i + delim + j] = get[j]
else:
val[i] = b[i]

return val

Результат выполнения этого фрагмента для вашего объекта JSON:

flattenjson({
"pk": 22,
"model": "auth.permission",
"fields": {
"codename": "add_message",
"name": "Can add message",
"content_type": 8
}
}, "__")

это

{
"pk": 22,
"model": "auth.permission",
"fields__codename": "add_message",
"fields__name": "Can add message",
"fields__content_type": 8
}

После применения этой функции к каждому dict во входном массиве объектов JSON:

input = map(lambda x: flattenjson( x, "__" ), input)

и поиск соответствующих имен столбцов:

columns = [x for row in input for x in row.keys()]
columns = list(set(columns))

запустить это несложно через модуль csv:

with open(fname, 'wb') as out_file:
csv_w = csv.writer(out_file)
csv_w.writerow(columns)

for i_r in input:
csv_w.writerow(map(lambda x: i_r.get(x, ""), columns))
Ответ 4

JSON может представлять широкий спектр структур данных - JS "объект" примерно похож на Python dict (со строковыми ключами), JS "массив" примерно похож на Python list, и вы можете вкладывать их, пока конечными "конечными" элементами являются числа или строки.

CSV может по существу представлять только двумерную таблицу - необязательно с первой строкой "заголовков", то есть "имен столбцов", что может сделать таблицу интерпретируемой как список dicts, вместо обычной интерпретации, список списков (опять же, "конечными" элементами могут быть числа или строки).

Итак, в общем случае вы не можете преобразовать произвольную структуру JSON в CSV. В нескольких особых случаях вы можете (массив массивов без дальнейшей вложенности; массивы объектов, все из которых имеют абсолютно одинаковые ключи). Какой особый случай, если таковой имеется, применим к вашей проблеме? Детали решения зависят от того, какой особый случай у вас есть. Учитывая удивительный факт, что вы даже не упоминаете, какой из них применим, я подозреваю, что вы, возможно, не учли ограничение, ни один из возможных вариантов на самом деле не применим, и вашу проблему решить невозможно. Но, пожалуйста, поясните!

2023-09-09 01:30 python json csv