Tengo un archivo JSON que quiero convertir a un archivo CSV. ¿Cómo puedo hacer esto con Python?
Lo intenté:
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()
Sin embargo, no funcionó. Estoy usando Django y el error que recibí es:
file' object has no attribute 'writerow'
Luego probé lo siguiente:
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()
Entonces recibo el error:
sequence expected
Archivo json de muestra:
[{
"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
}
}
]
jq
, como se describe aquí: stackoverflow.com/questions/32960857/…Respuestas:
Primero, su JSON tiene objetos anidados, por lo que normalmente no se puede convertir directamente a CSV. Necesitas cambiar eso a algo como esto:
Aquí está mi código para generar CSV a partir de eso:
Obtendrá salida como:
fuente
[u'
y']
. ¿Cuál es la solución alternativa (sin procesamiento posterior)? si hay uno ... :)TypeError: a bytes-like object is required, not 'str'
enf.writerow(['pk', 'model', 'codename', 'name', 'content_type'])
f = csv.writer(open("test.csv", "w", newline=''))
¡Con la
pandas
biblioteca , esto es tan fácil como usar dos comandos!Para convertir una cadena JSON en un objeto pandas (ya sea una serie o un marco de datos). Luego, suponiendo que los resultados se almacenaron como
df
:Que puede devolver una cadena o escribir directamente en un archivo csv.
Según la verbosidad de las respuestas anteriores, todos deberíamos agradecer a los pandas por el acceso directo.
fuente
.to_csv()
realmente potente (por ejemplo, filtrado de columnas gratuito). Necesito aprender pandas.orient='records'
debe establecerse, pero cada filafields
seguirá siendo undict
, que no es lo que solicitó el OP.Supongo que su archivo JSON se decodificará en una lista de diccionarios. Primero necesitamos una función que aplanará los objetos JSON:
El resultado de ejecutar este fragmento en su objeto JSON:
es
Después de aplicar esta función a cada dict en la matriz de entrada de objetos JSON:
y encontrar los nombres de columna relevantes:
No es difícil ejecutar esto a través del módulo csv:
¡Espero que esto ayude!
fuente
JSON puede representar una amplia variedad de estructuras de datos: un "objeto" JS es más o menos como un dict Python (con teclas de cadena), una "matriz" JS más o menos como una lista de Python, y puede anidarlos siempre que el "final" los elementos "hoja" son números o cadenas.
CSV puede representar esencialmente solo una tabla 2-D, opcionalmente con una primera fila de "encabezados", es decir, "nombres de columna", que pueden hacer que la tabla sea interpretable como una lista de dictados, en lugar de la interpretación normal, una lista de listas (de nuevo, los elementos "hoja" pueden ser números o cadenas).
Entonces, en el caso general, no puede traducir una estructura JSON arbitraria a un CSV. En algunos casos especiales puede (matriz de matrices sin anidamiento adicional; matrices de objetos que tienen exactamente las mismas claves). ¿Qué caso especial, si corresponde, se aplica a su problema? Los detalles de la solución dependen del caso especial que tenga. Dado el hecho sorprendente de que ni siquiera menciona cuál aplica, sospecho que puede que no haya considerado la restricción, de hecho, ninguno de los casos utilizables se aplica y su problema es imposible de resolver. Pero por favor aclarar!
fuente
Una solución genérica que traduce cualquier lista json de objetos planos a csv.
Pase el archivo input.json como primer argumento en la línea de comando.
fuente
Este código debería funcionar para usted, suponiendo que sus datos JSON estén en un archivo llamado
data.json
.fuente
csv_file.writerow
(no hay,f.writerow
por supuesto, ¡supongo que cometiste un error tipográfico allí!) Quiere una secuencia, no un dict, y en tu ejemplo, cada elemento es un dict. Esto funcionaría para el OTRO caso especial, como identifiqué en mi respuesta, donde el archivo JSON tiene una matriz de matrices; no funciona para una variedad de objetos, que es el caso especial que parece estar tratando de resolver (eso requiere uncsv.DictWriter
- y, por supuesto, necesita extraer los nombres de campo y decidir un orden para instanciarlo ! -).Será fácil de usar
csv.DictWriter()
, la implementación detallada puede ser así:Tenga en cuenta que esto supone que todos sus objetos JSON tienen los mismos campos.
Aquí está la referencia que puede ayudarlo.
fuente
Estaba teniendo problemas con la solución propuesta de Dan , pero esto funcionó para mí:
Donde "test.json" contenía lo siguiente:
fuente
Uso
json_normalize
depandas
:test.json
encoding='utf-8'
puede no ser necesariopathlib
biblioteca.open
es un método depathlib
Salida CSV:
Otros recursos para objetos JSON más anidados:
fuente
Como se mencionó en las respuestas anteriores, la dificultad para convertir json a csv se debe a que un archivo json puede contener diccionarios anidados y, por lo tanto, ser una estructura de datos multidimensional frente a un csv que es una estructura de datos 2D. Sin embargo, una buena manera de convertir una estructura multidimensional en un csv es tener múltiples csvs que se unan con las claves primarias.
En su ejemplo, la primera salida de csv tiene las columnas "pk", "model", "fields" como sus columnas. Los valores para "pk" y "model" son fáciles de obtener, pero debido a que la columna "fields" contiene un diccionario, debe ser su propio csv y porque "codename" parece ser la clave principal, puede usarlo como entrada para "campos" para completar el primer csv. El segundo csv contiene el diccionario de la columna "campos" con el nombre en clave como la clave principal que se puede usar para unir los 2 csvs.
Aquí hay una solución para su archivo json que convierte un diccionario anidado a 2 csvs.
fuente
Sé que ha pasado mucho tiempo desde que se hizo esta pregunta, pero pensé que podría agregar a la respuesta de todos los demás y compartir una publicación de blog que creo que explica la solución de una manera muy concisa.
Aqui esta el enlace
Abrir un archivo para escribir
Crear el objeto escritor csv
Asegúrese de cerrar el archivo para guardar el contenido
fuente
No es una forma muy inteligente de hacerlo, pero he tenido el mismo problema y esto funcionó para mí:
fuente
La respuesta de Alec es excelente, pero no funciona en el caso de que haya múltiples niveles de anidamiento. Aquí hay una versión modificada que admite múltiples niveles de anidamiento. También hace que los nombres de encabezado sean un poco más agradables si el objeto anidado ya especifica su propia clave (por ejemplo, datos de Firebase Analytics / BigTable / BigQuery):
fuente
Esto funciona relativamente bien. Aplana el json para escribirlo en un archivo csv. Los elementos anidados se gestionan :)
Eso es para Python 3
disfrutar.
fuente
json.loads
no funcionaba, lo hice funcionarjson.load
, lo que muy bien produce un objeto de lista. Tercero, se perdieron elementos anidados.Mi forma simple de resolver esto:
Cree un nuevo archivo Python como: json_to_csv.py
Agrega este código:
Después de agregar este código, guarde el archivo y ejecútelo en la terminal:
Espero que esto te ayude.
¡NOS VEMOS!
fuente
Sorprendentemente, descubrí que ninguna de las respuestas publicadas aquí hasta ahora trata correctamente todos los escenarios posibles (por ejemplo, dictados anidados, listas anidadas, valores de Ninguno, etc.).
Esta solución debería funcionar en todos los escenarios:
fuente
Prueba esto
fuente
Este código funciona para cualquier archivo json dado
fuente
Se modificó la respuesta de Alec McGail para admitir JSON con listas dentro
¡Gracias!
fuente
fuente
Si consideramos el siguiente ejemplo para convertir el archivo de formato json a un archivo con formato csv.
El siguiente código convertirá el archivo json (data3.json) a un archivo csv (data3.csv).
El código mencionado anteriormente se ha ejecutado en el pycharm instalado localmente y ha convertido con éxito el archivo json al archivo csv. Espero que esto ayude a convertir los archivos.
fuente
Dado que los datos parecen estar en formato de diccionario, parecería que debería usar csv.DictWriter () para generar las líneas con la información de encabezado adecuada. Esto debería permitir que la conversión se maneje algo más fácil. El parámetro de los nombres de campo configuraría el orden correctamente mientras que la salida de la primera línea como encabezados permitiría que csv.DictReader () leyera y procesara más tarde.
Por ejemplo, Mike Repass utilizó
Sin embargo, simplemente cambie la configuración inicial a output = csv.DictWriter (configuración de archivos, nombres de campo = datos [0] .keys ())
Tenga en cuenta que dado que el orden de los elementos en un diccionario no está definido, es posible que tenga que crear entradas de nombres de campo explícitamente. Una vez que hagas eso, el escritor funcionará. Las escrituras funcionan entonces como se muestra originalmente.
fuente
Desafortunadamente, no tengo suficiente reputación para hacer una pequeña contribución a la sorprendente respuesta de @Alec McGail. Estaba usando Python3 y he necesitado convertir el mapa a una lista después del comentario de @Alexis R.
Además, he encontrado que el escritor csv estaba agregando un CR adicional al archivo (tengo una línea vacía para cada línea con datos dentro del archivo csv). La solución fue muy fácil siguiendo la respuesta de @Jason R. Coombs a este hilo: CSV en Python agregando un retorno de carro adicional
Simplemente debe agregar el parámetro lineterminator = '\ n' al csv.writer. Será:
csv_w = csv.writer( out_file, lineterminator='\n' )
fuente
Puede usar este código para convertir un archivo json en un archivo csv Después de leer el archivo, estoy convirtiendo el objeto en un marco de datos de pandas y luego lo guardo en un archivo CSV
fuente
Puede que llegue tarde a la fiesta, pero creo que me he ocupado del problema similar. Tenía un archivo json que se veía así
Solo quería extraer algunas claves / valores de estos archivos json. Entonces, escribí el siguiente código para extraer el mismo.
Espero que esto sea de ayuda. Para obtener detalles sobre cómo funciona este código, puede consultar aquí
fuente
Esta es una modificación de la respuesta de @ MikeRepass. Esta versión escribe el CSV en un archivo y funciona tanto para Python 2 como para Python 3.
fuente