Voici mon code, des trucs vraiment 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éclarez certains noms de champs, le lecteur utilise CSV pour lire le fichier et les noms de fichiers pour vider le fichier au format JSON. Voici le problème ...
Chaque enregistrement du fichier CSV se trouve sur une ligne différente. Je veux que la sortie JSON soit la même chose. Le problème, c’est que le tout repose sur une longue et gigantesque ligne.
J'ai essayé d'utiliser quelque chose comme for line in csvfile:
, puis d'exécuter mon code ci-dessous avec reader = csv.DictReader( line, fieldnames)
qui parcourt chaque ligne, mais le fichier entier est placé sur une ligne, puis en boucle par le biais du fichier entier. ... continue jusqu'à ce qu'il n'y ait plus de lignes.
Des suggestions pour corriger cela?
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 recherche: (2 enregistrements sur 2 lignes)
{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"}
{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}
Pas chaque champ individuel en retrait/sur une ligne séparée, mais chaque enregistrement sur sa propre ligne.
Quelques exemples d’entrée.
"John","Doe","001","Message1"
"George","Washington","002","Message2"
Le problème avec votre sortie désirée est qu'il ne s'agit pas d'un document JSON valide; c'est un flux de documents json!
Ce n'est pas grave, 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
.
Comme la nouvelle ligne que vous souhaitez séparer de vos documents ne figure pas dans ces documents, vous êtes sur le point de le fournir vous-même. Il suffit donc de tirer la boucle de l'appel à json.dump et d'interposer des 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')
Vous pouvez utiliser Pandas DataFrame pour cela, 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)
J'ai pris la réponse de @ SingleNegationElimination et je l'ai simplifiée en trois lignes pouvant être utilisées 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')
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)
Vous pouvez essayer this
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)
Modifier:
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)
Ajoutez le paramètre indent
à json.dumps
data = {'this': ['has', 'some', 'things'],
'in': {'it': 'with', 'some': 'more'}}
print(json.dumps(data, indent=4))
Notez également que vous pouvez simplement utiliser json.dump
avec le fichier jsonfile
ouvert:
json.dump(data, jsonfile)
Que diriez-vous d'utiliser Pandas pour lire le fichier csv dans un DataFrame ( pd.read_csv ), puis manipuler les colonnes si vous le souhaitez (les supprimer ou les mettre à jour) et enfin convertir le DataFrame Retour à JSON ( pd.DataFrame.to_json ).
Remarque: Je n’ai pas vérifié son efficacité, mais c’est certainement l’un des moyens les plus simples de manipuler et de convertir un gros fichier .sv en json.
Je vois que c'est vieux, mais j'avais besoin du code de SingleNegationElimination, mais j'avais un problème avec les données contenant des caractères non-utf-8. Celles-ci sont apparues dans des domaines qui ne me préoccupaient pas trop, alors j'ai choisi de les ignorer. Cependant, cela a pris quelques efforts. Je suis nouveau sur python donc avec quelques essais et erreurs, je l’ai obtenu. 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 j'ai abandonné. Le code ci-dessous a fonctionné.
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 @MONTYHS, itérant à travers une multitude 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)