Comment convertir fichier CSV en JSON multiligne? [dupliquer]
cette question a déjà une réponse ici:
- Dumping plusieurs variables à disque en Json. Une variable par ligne 1 réponse
Voilà mon code, des trucs très simples...
import csv
import json
csvfile = open('file.csv', 'r')
jsonfile = open('file.json', 'w')
fieldnames = ("FirstName","LastName","IDNumber","Message")
reader = csv.DictReader( csvfile, fieldnames)
out = json.dumps( [ row for row in reader ] )
jsonfile.write(out)
déclare quelques noms de champ, le lecteur utilise CSV pour lire le fichier, et les noms déposés pour Dumper le fichier dans un format JSON. Voici le problème...
chaque enregistrement dans le fichier CSV est sur une ligne différente. Je veux que la sortie JSON soit la même. Le problème, c'est que tout est jeté sur une ligne géante.
j'ai essayé d'utiliser quelque chose comme for line in csvfile:
et puis d'exécuter mon code au-dessous de celui avec reader = csv.DictReader( line, fieldnames)
qui boucles à travers chaque ligne, mais il fait le fichier entier sur une ligne, puis boucles à travers le fichier entier sur une autre ligne... continue jusqu'à ce qu'il ne manque de lignes.
des suggestions pour corriger ceci?
Edit: Pour clarifier, actuellement, j'ai: (chaque enregistrement sur la ligne 1)
[{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"},{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}]
Ce que je cherche: (2 dossiers sur 2 lignes)
{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"}
{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}
pas chaque champ indenté/sur une ligne séparée, mais chaque enregistrement sur sa propre ligne.
quelques exemples.
"John","Doe","001","Message1"
"George","Washington","002","Message2"
10 réponses
le problème avec votre sortie désirée est qu'il n'est pas valide document json,; c'est un flux de documents json !
c'est bon, si c'est ce dont vous avez besoin, mais cela signifie que pour chaque document que vous voulez dans votre sortie, vous devrez appeler json.dumps
.
puisque la nouvelle ligne que vous voulez séparer vos documents n'est pas contenue dans ces documents, vous êtes sur le crochet pour fournir vous-même. Donc nous avons juste besoin de tirer sortie de la boucle de l'appel en json.videz et interposez les nouvelles lignes pour chaque document écrit.
import csv
import json
csvfile = open('file.csv', 'r')
jsonfile = open('file.json', 'w')
fieldnames = ("FirstName","LastName","IDNumber","Message")
reader = csv.DictReader( csvfile, fieldnames)
for row in reader:
json.dump(row, jsonfile)
jsonfile.write('\n')
j'ai pris la réponse de @SingleNegationElimination et je l'ai simplifiée en une doublure qui peut être utilisée dans un pipeline:
import csv
import json
import sys
for row in csv.DictReader(sys.stdin):
json.dump(row, sys.stdout)
sys.stdout.write('\n')
vous pouvez essayer ce
import csvmapper
# how does the object look
mapper = csvmapper.DictMapper([
[
{ 'name' : 'FirstName'},
{ 'name' : 'LastName' },
{ 'name' : 'IDNumber', 'type':'int' },
{ 'name' : 'Messages' }
]
])
# parser instance
parser = csvmapper.CSVParser('sample.csv', mapper)
# conversion service
converter = csvmapper.JSONConverter(parser)
print converter.doConvert(pretty=True)
Edit:
approche plus simple
import csvmapper
fields = ('FirstName', 'LastName', 'IDNumber', 'Messages')
parser = CSVParser('sample.csv', csvmapper.FieldMapper(fields))
converter = csvmapper.JSONConverter(parser)
print converter.doConvert(pretty=True)
vous pouvez utiliser Pandas DataFrame pour ce faire, avec l'exemple suivant:
import pandas as pd
csv_file = pd.DataFrame(pd.read_csv("path/to/file.csv", sep = ",", header = 0, index_col = False))
csv_file.to_json("/path/to/new/file.json", orient = "records", date_format = "epoch", double_precision = 10, force_ascii = True, date_unit = "ms", default_handler = None)
ajouter le paramètre indent
à json.dumps
data = {'this': ['has', 'some', 'things'],
'in': {'it': 'with', 'some': 'more'}}
print(json.dumps(data, indent=4))
notez aussi que, vous pouvez simplement utiliser json.dump
avec le jsonfile
ouvert:
json.dump(data, jsonfile)
import csv
import json
file = 'csv_file_name.csv'
json_file = 'output_file_name.json'
#Read CSV File
def read_CSV(file, json_file):
csv_rows = []
with open(file) as csvfile:
reader = csv.DictReader(csvfile)
field = reader.fieldnames
for row in reader:
csv_rows.extend([{field[i]:row[field[i]] for i in range(len(field))}])
convert_write_json(csv_rows, json_file)
#Convert csv data into json
def convert_write_json(data, json_file):
with open(json_file, "w") as f:
f.write(json.dumps(data, sort_keys=False, indent=4, separators=(',', ': '))) #for pretty
f.write(json.dumps(data))
read_CSV(file,json_file)
pourquoi ne pas utiliser Pandas pour lire le fichier csv dans une DataFrame ( pd.read_csv ), puis en manipulant les colonnes si vous le souhaitez (en les laissant tomber ou en mettant à jour les valeurs) et enfin en convertissant la DataFrame de nouveau en JSON ( pd.DataFrame.to_json ).
Note: Je n'ai pas vérifié à quel point ce sera efficace, mais c'est certainement l'une des façons les plus faciles de manipuler et de convertir un grand csv en json.
je vois que c'est vieux mais j'avais besoin du code de SingleNegationElimination cependant j'ai eu des problèmes avec les données contenant des caractères non utf-8. Ceux-ci sont apparus dans les domaines que je ne me souciais pas trop, donc j'ai choisi de les ignorer. Cependant que a fallu un certain effort. Je suis nouveau sur python donc avec quelques tâtonnements, j'ai réussi à le faire fonctionner. Le code est une copie de SingleNegationElimination avec le traitement supplémentaire de utf-8. J'ai essayé de le faire avec https://docs.python.org/2.7/library/csv.html mais à la fin a abandonné. Le code ci-dessous travaillé.
import csv, json
csvfile = open('file.csv', 'r')
jsonfile = open('file.json', 'w')
fieldnames = ("Scope","Comment","OOS Code","In RMF","Code","Status","Name","Sub Code","CAT","LOB","Description","Owner","Manager","Platform Owner")
reader = csv.DictReader(csvfile , fieldnames)
code = ''
for row in reader:
try:
print('+' + row['Code'])
for key in row:
row[key] = row[key].decode('utf-8', 'ignore').encode('utf-8')
json.dump(row, jsonfile)
jsonfile.write('\n')
except:
print('-' + row['Code'])
raise
comme une légère amélioration à la réponse de @MONTYHS, itérant à travers un coup de noms de champs:
import csv
import json
csvfilename = 'filename.csv'
jsonfilename = csvfilename.split('.')[0] + '.json'
csvfile = open(csvfilename, 'r')
jsonfile = open(jsonfilename, 'w')
reader = csv.DictReader(csvfile)
fieldnames = ('FirstName', 'LastName', 'IDNumber', 'Message')
output = []
for each in reader:
row = {}
for field in fieldnames:
row[field] = each[field]
output.append(row)
json.dump(output, jsonfile, indent=2, sort_keys=True)
import csv
import json
csvfile = csv.DictReader('filename.csv', 'r'))
output =[]
for each in csvfile:
row ={}
row['FirstName'] = each['FirstName']
row['LastName'] = each['LastName']
row['IDNumber'] = each ['IDNumber']
row['Message'] = each['Message']
output.append(row)
json.dump(output,open('filename.json','w'),indent=4,sort_keys=False)