Ik heb een JSON-bestand dat ik naar een CSV-bestand wil converteren. Hoe kan ik dit doen met Python?
Ik heb het geprobeerd:
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()
Het werkte echter niet. Ik gebruik Django en de foutmelding die ik heb gekregen is:
`file' object has no attribute 'writerow'`
Ik heb toen het volgende geprobeerd:
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()
Ik krijg dan de foutmelding:
`sequence expected`
Voorbeeld json-bestand:
[{
"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
}
}
]
Antwoord 1, autoriteit 100%
Met de pandas
bibliotheek, dit is net zo eenvoudig als het gebruik van twee commando’s!
df = pd.read_json()
read_jsonconverteert een JSON-tekenreeks naar een panda-object (een serie of dataframe). Dan:
df.to_csv()
Die een string kan retourneren of rechtstreeks naar een csv-bestand kan schrijven. Zie de documenten voor to_csv.
Op basis van de uitgebreidheid van eerdere antwoorden, moeten we allemaal panda’s bedanken voor de kortere weg.
Voor ongestructureerde JSON zie dit antwoord.
Antwoord 2, autoriteit 81%
Ten eerste heeft uw JSON geneste objecten, dus deze kan normaal gesproken niet rechtstreeks naar CSV worden geconverteerd. Je moet dat veranderen in iets als dit:
{
"pk": 22,
"model": "auth.permission",
"codename": "add_logentry",
"content_type": 8,
"name": "Can add log entry"
},
......]
Hier is mijn code om daaruit CSV te genereren:
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"]])
U krijgt uitvoer als:
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
Antwoord 3, autoriteit 57%
Ik ga ervan uit dat uw JSON-bestand wordt gedecodeerd in een lijst met woordenboeken. Eerst hebben we een functie nodig die de JSON-objecten zal afvlakken:
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
Het resultaat van het uitvoeren van dit fragment op uw JSON-object:
flattenjson({
"pk": 22,
"model": "auth.permission",
"fields": {
"codename": "add_message",
"name": "Can add message",
"content_type": 8
}
}, "__")
is
{
"pk": 22,
"model": "auth.permission",
"fields__codename": "add_message",
"fields__name": "Can add message",
"fields__content_type": 8
}
Nadat u deze functie hebt toegepast op elke dict in de ingangsreeks van JSON OBJECTEN:
input = map(lambda x: flattenjson( x, "__" ), input)
en het vinden van de relevante kolomnamen:
columns = [x for row in input for x in row.keys()]
columns = list(set(columns))
Het is niet moeilijk om dit te draaien via de CSV-module:
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))
Ik hoop dat dit helpt!
4, Autoriteit 22%
JSON kan een breed scala aan data-structuren vertegenwoordigen – een JS “-object” is ongeveer als een python-dict (met string-toetsen), een JS “-array” ongeveer als een Python-lijst, en je kunt ze zo lang nesten De laatste “blad” -elementen zijn getallen of snaren.
CSV kan in essentie slechts een 2-D-tabel vertegenwoordigen – optioneel met een eerste rij “headers”, dat wil zeggen “kolomnamen”, die de tabel interpreteerbaar kan maken als een lijst met dictten, in plaats van de normale interpretatie, Een lijst met lijsten (opnieuw, “blad” -elementen kunnen cijfers of snaren zijn).
Dus, in het algemene geval, kunt u een willekeurige JSON-structuur niet vertalen naar een CSV. In een paar speciale gevallen kunt u (array van arrays zonder nesten; arrays van objecten die allemaal precies dezelfde toetsen hebben). Welk speciaal geval, indien aanwezig, van toepassing is op uw probleem? De details van de oplossing zijn afhankelijk van welk speciaal geval dat u wel hebt. Gezien het verbazingwekkende feit dat u niet eens vermeldt welke men van toepassing is, vermoed ik dat u de beperking niet hebt overwogen, geen van beide bruikbare zaak in feite van toepassing is, en uw probleem is onmogelijk om op te lossen. Maar alsjeblieft verduidelijken!
5, Autoriteit 17%
een generieke oplossing die elke JSON-lijst van platte objecten naar CSV vertaalt.
Passeer het invoer.json-bestand als eerste argument op de opdrachtregel.
import csv, json, sys
input = open(sys.argv[1])
data = json.load(input)
input.close()
output = csv.writer(sys.stdout)
output.writerow(data[0].keys()) # header row
for row in data:
output.writerow(row.values())
Antwoord 6, autoriteit 11%
Het zal gemakkelijk zijn om csv.DictWriter()
te gebruiken, de gedetailleerde implementatie kan als volgt zijn:
def read_json(filename):
return json.loads(open(filename).read())
def write_csv(data,filename):
with open(filename, 'w+') as outf:
writer = csv.DictWriter(outf, data[0].keys())
writer.writeheader()
for row in data:
writer.writerow(row)
# implement
write_csv(read_json('test.json'), 'output.csv')
Houd er rekening mee dat dit ervan uitgaat dat al uw JSON-objecten dezelfde velden hebben.
Hier is de referentiedie u kan helpen.
Antwoord 7, autoriteit 8%
Gebruik json_normalize
van pandas
:
- Gezien de voorbeeldgegevens van het OP, in een bestand met de naam
test.json
. encoding='utf-8'
is hier gebruikt, maar is mogelijk niet nodig voor andere gevallen.- De volgende code maakt gebruik van de
pathlib
bibliotheek..open
is een methode vanpathlib
.- Werkt ook met niet-Windows-paden.
- Gebruik
pandas.to_csv(...)
om de gegevens op te slaan in een csv-bestand.
import pandas as pd
# As of Pandas 1.01, json_normalize as pandas.io.json.json_normalize is deprecated and is now exposed in the top-level namespace.
# from pandas.io.json import json_normalize
from pathlib import Path
import json
# set path to file
p = Path(r'c:\some_path_to_file\test.json')
# read json
with p.open('r', encoding='utf-8') as f:
data = json.loads(f.read())
# create dataframe
df = pd.json_normalize(data)
# dataframe view
pk model fields.codename fields.name fields.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
4 auth.permission add_group Can add group 2
10 auth.permission add_message Can add message 4
# save to csv
df.to_csv('test.csv', index=False, encoding='utf-8')
CSV-uitvoer:
pk,model,fields.codename,fields.name,fields.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
4,auth.permission,add_group,Can add group,2
10,auth.permission,add_message,Can add message,4
Bronnen voor zwaarder geneste JSON-objecten:
- ZO Antwoorden:
Antwoord 8, autoriteit 3%
Ik had problemen met Dan’s voorgestelde oplossing, maar dit werkte voor mij:
import json
import csv
f = open('test.json')
data = json.load(f)
f.close()
f=csv.writer(open('test.csv','wb+'))
for item in data:
f.writerow([item['pk'], item['model']] + item['fields'].values())
Waarin “test.json” het volgende bevatte:
[
{"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 } }
]
Antwoord 9, autoriteit 3%
Alecs antwoordis geweldig, maar het werkt niet in het geval dat er meerdere niveaus van nesten zijn. Hier is een aangepaste versie die meerdere niveaus van nesten ondersteunt. Het maakt de headernamen ook een beetje mooier als het geneste object al zijn eigen sleutel specificeert (bijvoorbeeld Firebase Analytics / BigTable / BigQuery-gegevens):
"""Converts JSON with nested fields into a flattened CSV file.
"""
import sys
import json
import csv
import os
import jsonlines
from orderedset import OrderedSet
# from https://stackoverflow.com/a/28246154/473201
def flattenjson( b, prefix='', delim='/', val=None ):
if val is None:
val = {}
if isinstance( b, dict ):
for j in b.keys():
flattenjson(b[j], prefix + delim + j, delim, val)
elif isinstance( b, list ):
get = b
for j in range(len(get)):
key = str(j)
# If the nested data contains its own key, use that as the header instead.
if isinstance( get[j], dict ):
if 'key' in get[j]:
key = get[j]['key']
flattenjson(get[j], prefix + delim + key, delim, val)
else:
val[prefix] = b
return val
def main(argv):
if len(argv) < 2:
raise Error('Please specify a JSON file to parse')
print "Loading and Flattening..."
filename = argv[1]
allRows = []
fieldnames = OrderedSet()
with jsonlines.open(filename) as reader:
for obj in reader:
# print 'orig:\n'
# print obj
flattened = flattenjson(obj)
#print 'keys: %s' % flattened.keys()
# print 'flattened:\n'
# print flattened
fieldnames.update(flattened.keys())
allRows.append(flattened)
print "Exporting to CSV..."
outfilename = filename + '.csv'
count = 0
with open(outfilename, 'w') as file:
csvwriter = csv.DictWriter(file, fieldnames=fieldnames)
csvwriter.writeheader()
for obj in allRows:
# print 'allRows:\n'
# print obj
csvwriter.writerow(obj)
count += 1
print "Wrote %d rows" % count
if __name__ == '__main__':
main(sys.argv)
10, Autoriteit 2%
Zoals vermeld in de vorige antwoorden, is de moeilijkheid bij het converteren van json naar csv omdat een json-bestand geneste woordenboeken kan bevatten en daarom een multidimensionale gegevensstructuur kan zijn in plaats van een csv die een 2D-gegevensstructuur is. Een goede manier om een multidimensionale structuur om te zetten in een csv is echter om meerdere csv’s te hebben die aan elkaar zijn gekoppeld met primaire sleutels.
In uw voorbeeld heeft de eerste csv-uitvoer de kolommen “pk”, “model”, “velden” als uw kolommen. Waarden voor “pk” en “model” zijn gemakkelijk te verkrijgen, maar omdat de kolom “fields” een woordenboek bevat, zou het zijn eigen csv moeten zijn en omdat “codenaam” de primaire sleutel lijkt te zijn, kunt u deze als invoer gebruiken voor “velden” om de eerste csv te voltooien. De tweede csv bevat het woordenboek uit de kolom “fields” met codenaam als de primaire sleutel die kan worden gebruikt om de 2 csv’s aan elkaar te koppelen.
Hier is een oplossing voor uw json-bestand dat geneste woordenboeken converteert naar 2 csv’s.
import csv
import json
def readAndWrite(inputFileName, primaryKey=""):
input = open(inputFileName+".json")
data = json.load(input)
input.close()
header = set()
if primaryKey != "":
outputFileName = inputFileName+"-"+primaryKey
if inputFileName == "data":
for i in data:
for j in i["fields"].keys():
if j not in header:
header.add(j)
else:
outputFileName = inputFileName
for i in data:
for j in i.keys():
if j not in header:
header.add(j)
with open(outputFileName+".csv", 'wb') as output_file:
fieldnames = list(header)
writer = csv.DictWriter(output_file, fieldnames, delimiter=',', quotechar='"')
writer.writeheader()
for x in data:
row_value = {}
if primaryKey == "":
for y in x.keys():
yValue = x.get(y)
if type(yValue) == int or type(yValue) == bool or type(yValue) == float or type(yValue) == list:
row_value[y] = str(yValue).encode('utf8')
elif type(yValue) != dict:
row_value[y] = yValue.encode('utf8')
else:
if inputFileName == "data":
row_value[y] = yValue["codename"].encode('utf8')
readAndWrite(inputFileName, primaryKey="codename")
writer.writerow(row_value)
elif primaryKey == "codename":
for y in x["fields"].keys():
yValue = x["fields"].get(y)
if type(yValue) == int or type(yValue) == bool or type(yValue) == float or type(yValue) == list:
row_value[y] = str(yValue).encode('utf8')
elif type(yValue) != dict:
row_value[y] = yValue.encode('utf8')
writer.writerow(row_value)
readAndWrite("data")
Antwoord 11, autoriteit 2%
Ik weet dat het lang geleden is dat deze vraag is gesteld, maar ik dacht dat ik misschien iets aan het antwoord van iedereen zou kunnen toevoegen en een blogpost zou kunnen delen waarin ik denk dat de oplossing op een zeer beknopte manier wordt uitgelegd.
Hier is de link
Open een bestand om te schrijven
employ_data = open('/tmp/EmployData.csv', 'w')
Maak het csv-schrijverobject
csvwriter = csv.writer(employ_data)
count = 0
for emp in emp_data:
if count == 0:
header = emp.keys()
csvwriter.writerow(header)
count += 1
csvwriter.writerow(emp.values())
Zorg ervoor dat u het bestand sluit om de inhoud op te slaan
employ_data.close()
Antwoord 12, autoriteit 2%
Het is niet zo’n slimme manier om het te doen, maar ik heb hetzelfde probleem gehad en dit werkte voor mij:
import csv
f = open('data.json')
data = json.load(f)
f.close()
new_data = []
for i in data:
flat = {}
names = i.keys()
for n in names:
try:
if len(i[n].keys()) > 0:
for ii in i[n].keys():
flat[n+"_"+ii] = i[n][ii]
except:
flat[n] = i[n]
new_data.append(flat)
f = open(filename, "r")
writer = csv.DictWriter(f, new_data[0].keys())
writer.writeheader()
for row in new_data:
writer.writerow(row)
f.close()
Antwoord 13
Dit werkt relatief goed.
Het maakt de json plat om het naar een csv-bestand te schrijven.
Geneste elementen worden beheerd 🙂
Dat is voor python 3
import json
o = json.loads('your json string') # Be careful, o must be a list, each of its objects will make a line of the csv.
def flatten(o, k='/'):
global l, c_line
if isinstance(o, dict):
for key, value in o.items():
flatten(value, k + '/' + key)
elif isinstance(o, list):
for ov in o:
flatten(ov, '')
elif isinstance(o, str):
o = o.replace('\r',' ').replace('\n',' ').replace(';', ',')
if not k in l:
l[k]={}
l[k][c_line]=o
def render_csv(l):
ftime = True
for i in range(100): #len(l[list(l.keys())[0]])
for k in l:
if ftime :
print('%s;' % k, end='')
continue
v = l[k]
try:
print('%s;' % v[i], end='')
except:
print(';', end='')
print()
ftime = False
i = 0
def json_to_csv(object_list):
global l, c_line
l = {}
c_line = 0
for ov in object_list : # Assumes json is a list of objects
flatten(ov)
c_line += 1
render_csv(l)
json_to_csv(o)
geniet.
Antwoord 14
Mijn eenvoudige manier om dit op te lossen:
Maak een nieuw Python-bestand zoals: json_to_csv.py
Voeg deze code toe:
import csv, json, sys
#if you are not using utf-8 files, remove the next line
sys.setdefaultencoding("UTF-8")
#check if you pass the input file and output file
if sys.argv[1] is not None and sys.argv[2] is not None:
fileInput = sys.argv[1]
fileOutput = sys.argv[2]
inputFile = open(fileInput)
outputFile = open(fileOutput, 'w')
data = json.load(inputFile)
inputFile.close()
output = csv.writer(outputFile)
output.writerow(data[0].keys()) # header row
for row in data:
output.writerow(row.values())
Na het toevoegen van deze code, sla het bestand op en voer het uit op de terminal:
python json_to_csv.py input.txt output.csv
Ik hoop dat dit je helpt.
SEEYA!
Antwoord 15
Verrassend genoeg ontdekte ik dat geen van de antwoorden die hier tot nu toe zijn gepost correct alle mogelijke scenario’s behandelt (bijv. geneste dictaten, geneste lijsten, Geen waarden, enz.).
Deze oplossing zou in alle scenario’s moeten werken:
def flatten_json(json):
def process_value(keys, value, flattened):
if isinstance(value, dict):
for key in value.keys():
process_value(keys + [key], value[key], flattened)
elif isinstance(value, list):
for idx, v in enumerate(value):
process_value(keys + [str(idx)], v, flattened)
else:
flattened['__'.join(keys)] = value
flattened = {}
for key in json.keys():
process_value([key], json[key], flattened)
return flattened
Antwoord 16
Probeer dit
import csv, json, sys
input = open(sys.argv[1])
data = json.load(input)
input.close()
output = csv.writer(sys.stdout)
output.writerow(data[0].keys()) # header row
for item in data:
output.writerow(item.values())
Antwoord 17
Deze code werkt voor elk gegeven json-bestand
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 17 20:35:35 2019
author: Ram
"""
import json
import csv
with open("file1.json") as file:
data = json.load(file)
# create the csv writer object
pt_data1 = open('pt_data1.csv', 'w')
csvwriter = csv.writer(pt_data1)
count = 0
for pt in data:
if count == 0:
header = pt.keys()
csvwriter.writerow(header)
count += 1
csvwriter.writerow(pt.values())
pt_data1.close()
Antwoord 18
Dit is een wijziging van het antwoord van @MikeRepass. Deze versie schrijft de CSV naar een bestand en werkt voor zowel Python 2 als Python 3.
import csv,json
input_file="data.json"
output_file="data.csv"
with open(input_file) as f:
content=json.load(f)
try:
context=open(output_file,'w',newline='') # Python 3
except TypeError:
context=open(output_file,'wb') # Python 2
with context as file:
writer=csv.writer(file)
writer.writerow(content[0].keys()) # header row
for row in content:
writer.writerow(row.values())
Antwoord 19
Alec McGail’s antwoord aangepast om JSON te ondersteunen met lijsten erin
def flattenjson(self, mp, delim="|"):
ret = []
if isinstance(mp, dict):
for k in mp.keys():
csvs = self.flattenjson(mp[k], delim)
for csv in csvs:
ret.append(k + delim + csv)
elif isinstance(mp, list):
for k in mp:
csvs = self.flattenjson(k, delim)
for csv in csvs:
ret.append(csv)
else:
ret.append(mp)
return ret
Bedankt!
Antwoord 20
import json,csv
t=''
t=(type('a'))
json_data = []
data = None
write_header = True
item_keys = []
try:
with open('kk.json') as json_file:
json_data = json_file.read()
data = json.loads(json_data)
except Exception as e:
print( e)
with open('bar.csv', 'at') as csv_file:
writer = csv.writer(csv_file)#, quoting=csv.QUOTE_MINIMAL)
for item in data:
item_values = []
for key in item:
if write_header:
item_keys.append(key)
value = item.get(key, '')
if (type(value)==t):
item_values.append(value.encode('utf-8'))
else:
item_values.append(value)
if write_header:
writer.writerow(item_keys)
write_header = False
writer.writerow(item_values)
Antwoord 21
Als we het onderstaande voorbeeld beschouwen voor het converteren van het bestand in json-indeling naar bestand in csv-indeling.
{
"item_data" : [
{
"item": "10023456",
"class": "100",
"subclass": "123"
}
]
}
De onderstaande code converteert het json-bestand ( data3.json ) naar csv-bestand ( data3.csv ).
import json
import csv
with open("/Users/Desktop/json/data3.json") as file:
data = json.load(file)
file.close()
print(data)
fname = "/Users/Desktop/json/data3.csv"
with open(fname, "w", newline='') as file:
csv_file = csv.writer(file)
csv_file.writerow(['dept',
'class',
'subclass'])
for item in data["item_data"]:
csv_file.writerow([item.get('item_data').get('dept'),
item.get('item_data').get('class'),
item.get('item_data').get('subclass')])
De bovengenoemde code is uitgevoerd in de lokaal geïnstalleerde pycharm en heeft het json-bestand met succes geconverteerd naar het csv-bestand. Ik hoop dat dit helpt om de bestanden te converteren.
Antwoord 22
Aangezien de gegevens in een woordenboekformaat lijken te zijn, lijkt het erop dat u csv.DictWriter() daadwerkelijk zou moeten gebruiken om de regels met de juiste koptekstinformatie uit te voeren. Dit zou de conversie wat gemakkelijker moeten laten verlopen. De parameter fieldnames zou dan de volgorde correct instellen, terwijl de uitvoer van de eerste regel als de headers het later door csv.DictReader() zou laten lezen en verwerken.
Bijvoorbeeld Mike Repass gebruikte
output = csv.writer(sys.stdout)
output.writerow(data[0].keys()) # header row
for row in data:
output.writerow(row.values())
Verander de initiële instellingen echter gewoon in
output = csv.DictWriter(bestandsinstelling, veldnamen=data[0].keys())
Houd er rekening mee dat, aangezien de volgorde van elementen in een woordenboek niet is gedefinieerd, u veldnamen mogelijk expliciet moet maken. Zodra u dat doet, zal de writerow werken. De schrijfbewerkingen werken dan zoals oorspronkelijk getoond.
Antwoord 23
Helaas heb ik niet genoeg reputatie om een kleine bijdrage te leveren aan het geweldige antwoord van @Alec McGail.
Ik gebruikte Python3 en ik moest de kaart converteren naar een lijst na de @Alexis R-opmerking.
Bovendien heb ik ontdekt dat de csv-schrijver een extra CR aan het bestand toevoegde (ik heb een lege regel voor elke regel met gegevens in het csv-bestand). De oplossing was heel eenvoudig na het antwoord van @Jason R. Coombs op deze thread:
CSV in Python met een extra regelterugloop
Je hoeft alleen maar de parameter lineterminator=’\n’ toe te voegen aan de csv.writer. Het wordt: csv_w = csv.writer( out_file, lineterminator='\n' )
Antwoord 24
U kunt deze code gebruiken om een json-bestand naar een csv-bestand te converteren
Nadat ik het bestand heb gelezen, converteer ik het object naar pandas-dataframe en sla ik dit op in een CSV-bestand
import os
import pandas as pd
import json
import numpy as np
data = []
os.chdir('D:\\Your_directory\\folder')
with open('file_name.json', encoding="utf8") as data_file:
for line in data_file:
data.append(json.loads(line))
dataframe = pd.DataFrame(data)
## Saving the dataframe to a csv file
dataframe.to_csv("filename.csv", encoding='utf-8',index= False)
Antwoord 25
Misschien ben ik te laat op het feest, maar ik denk dat ik hetzelfde probleem heb gehad. Ik had een json-bestand dat er zo uitzag
Ik wilde maar een paar sleutels/waarden uit dit json-bestand halen. Dus schreef ik de volgende code om hetzelfde te extraheren.
"""json_to_csv.py
This script reads n numbers of json files present in a folder and then extract certain data from each file and write in a csv file.
The folder contains the python script i.e. json_to_csv.py, output.csv and another folder descriptions containing all the json files.
"""
import os
import json
import csv
def get_list_of_json_files():
"""Returns the list of filenames of all the Json files present in the folder
Parameter
---------
directory : str
'descriptions' in this case
Returns
-------
list_of_files: list
List of the filenames of all the json files
"""
list_of_files = os.listdir('descriptions') # creates list of all the files in the folder
return list_of_files
def create_list_from_json(jsonfile):
"""Returns a list of the extracted items from json file in the same order we need it.
Parameter
_________
jsonfile : json
The json file containing the data
Returns
-------
one_sample_list : list
The list of the extracted items needed for the final csv
"""
with open(jsonfile) as f:
data = json.load(f)
data_list = [] # create an empty list
# append the items to the list in the same order.
data_list.append(data['_id'])
data_list.append(data['_modelType'])
data_list.append(data['creator']['_id'])
data_list.append(data['creator']['name'])
data_list.append(data['dataset']['_accessLevel'])
data_list.append(data['dataset']['_id'])
data_list.append(data['dataset']['description'])
data_list.append(data['dataset']['name'])
data_list.append(data['meta']['acquisition']['image_type'])
data_list.append(data['meta']['acquisition']['pixelsX'])
data_list.append(data['meta']['acquisition']['pixelsY'])
data_list.append(data['meta']['clinical']['age_approx'])
data_list.append(data['meta']['clinical']['benign_malignant'])
data_list.append(data['meta']['clinical']['diagnosis'])
data_list.append(data['meta']['clinical']['diagnosis_confirm_type'])
data_list.append(data['meta']['clinical']['melanocytic'])
data_list.append(data['meta']['clinical']['sex'])
data_list.append(data['meta']['unstructured']['diagnosis'])
# In few json files, the race was not there so using KeyError exception to add '' at the place
try:
data_list.append(data['meta']['unstructured']['race'])
except KeyError:
data_list.append("") # will add an empty string in case race is not there.
data_list.append(data['name'])
return data_list
def write_csv():
"""Creates the desired csv file
Parameters
__________
list_of_files : file
The list created by get_list_of_json_files() method
result.csv : csv
The csv file containing the header only
Returns
_______
result.csv : csv
The desired csv file
"""
list_of_files = get_list_of_json_files()
for file in list_of_files:
row = create_list_from_json(f'descriptions/{file}') # create the row to be added to csv for each file (json-file)
with open('output.csv', 'a') as c:
writer = csv.writer(c)
writer.writerow(row)
c.close()
if __name__ == '__main__':
write_csv()
Ik hoop dat dit zal helpen. Voor details over hoe deze code werkt, kun je hier