Как я могу преобразовать 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. В нескольких особых случаях вы можете (массив массивов без дальнейшей вложенности; массивы объектов, все из которых имеют абсолютно одинаковые ключи). Какой особый случай, если таковой имеется, применим к вашей проблеме? Детали решения зависят от того, какой особый случай у вас есть. Учитывая удивительный факт, что вы даже не упоминаете, какой из них применим, я подозреваю, что вы, возможно, не учли ограничение, ни один из возможных вариантов на самом деле не применим, и вашу проблему решить невозможно. Но, пожалуйста, поясните!