Aquí está mi código, cosas realmente 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)
Declare algunos nombres de campo, el lector usa CSV para leer el archivo y los nombres archivados para volcar el archivo en formato JSON. Aquí está el problema ...
Cada registro del archivo CSV está en una fila diferente. Quiero que la salida JSON sea la misma. El problema es que lo arroja todo en una línea gigante y larga.
Intenté usar algo como for line in csvfile:
y luego ejecutar mi código debajo de eso con lo reader = csv.DictReader( line, fieldnames)
que recorre cada línea, pero hace todo el archivo en una línea, luego recorre todo el archivo en otra línea ... continúa hasta que se agota las líneas .
¿Alguna sugerencia para corregir esto?
Editar: Para aclarar, actualmente tengo: (todos los registros en la línea 1)
[{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"},{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}]
Lo que estoy buscando: (2 registros en 2 líneas)
{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"}
{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}
No cada campo individual sangrado / en una línea separada, pero cada registro en su propia línea.
Alguna entrada de muestra.
"John","Doe","001","Message1"
"George","Washington","002","Message2"
[{..row..},{..row..},...]
no{..row..}{..row..}..
. Es decir, la salida parece ser una matriz json de objetos json, no un flujo de objetos json no conectados.Respuestas:
El problema con la salida deseada es que no es un documento json válido; es un flujo de documentos json !
Está bien, si es lo que necesita, pero eso significa que para cada documento que desee en su salida, tendrá que llamar
json.dumps
.Dado que la nueva línea que desea que separe sus documentos no está contenida en esos documentos, está en la obligación de proporcionarla usted mismo. Así que solo necesitamos sacar el bucle de la llamada a json.dump e interponer nuevas líneas para cada documento escrito.
fuente
DictReader
sin dar unfieldnames
argumento; luego leerá la primera línea para obtener los nombres de campo del archivo.csvfile = open('file.csv', 'r',encoding='utf-8')
yjsonfile = open('file.json', 'w',encoding='utf-8')
Puede usar Pandas DataFrame para lograr esto, con el siguiente ejemplo:
fuente
Tomé la respuesta de @ SingleNegationElimination y la simplifiqué en tres líneas que se pueden usar en una canalización:
fuente
Documentación de json.dumps ()
fuente
Puedes probar esto
Editar:
Enfoque más simple
fuente
csvmapper
, para hacer esto (y tal vez dónde conseguirlo) en lugar de algo integrado.Agregue el
indent
parámetro ajson.dumps
También tenga en cuenta que, simplemente puede usar
json.dump
con el abiertojsonfile
:fuente
Veo que esto es antiguo, pero necesitaba el código de SingleNegationElimination, sin embargo, tuve un problema con los datos que contenían caracteres que no eran utf-8. Estos aparecieron en campos que no me preocupaban demasiado, así que decidí ignorarlos. Sin embargo, eso requirió un poco de esfuerzo. Soy nuevo en Python, así que con un poco de prueba y error lo hice funcionar. El código es una copia de SingleNegationElimination con el manejo adicional de utf-8. Traté de hacerlo con https://docs.python.org/2.7/library/csv.html pero al final me rendí. El siguiente código funcionó.
fuente
¿Qué tal usar Pandas para leer el archivo csv en un DataFrame ( pd.read_csv ), luego manipular las columnas si lo desea (soltarlas o actualizar valores) y finalmente convertir el DataFrame de nuevo a JSON ( pd.DataFrame.to_json )?
Nota: No he comprobado qué tan eficiente será esto, pero esta es definitivamente una de las formas más fáciles de manipular y convertir un csv grande a json.
fuente
Como una ligera mejora a la respuesta de @MONTYHS, iterando a través de una serie de nombres de campo:
fuente
fuente
DictReader
, por lo que está adivinando los nombres de campo de la primera línea del archivo de entrada: John, Doe, 5, "Ninguno" en lugar de "Nombre, apellido" y así sucesivamente ...TypeError: expected string or buffer