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"
57
demandé sur martineau 2013-10-31 07:15:15

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')
89
répondu SingleNegationElimination 2013-10-31 12:49:43

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')
6
répondu Lawrence I. Siden 2015-11-25 22:25:17

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)
6
répondu Snork S 2016-08-23 14:57:43

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)
3
répondu Naufal 2017-02-02 12:13:15

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)
2
répondu Wayne Werner 2013-10-31 03:19:43
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)

Documentation de json.dumps ()

2
répondu Laxman 2018-01-06 19:58:46

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.

1
répondu impiyush 2016-07-07 17:10:20

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
1
répondu Mark Channing 2016-08-18 15:50:42

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)
0
répondu GarciadelCastillo 2014-03-05 19:43:35
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)
-1
répondu MONTYHS 2013-10-31 12:03:05