Aqui está meu código, coisas muito 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 alguns nomes de campo, o leitor usa CSV para ler o arquivo e os nomes de arquivo para despejar o arquivo em um formato JSON. Aqui está o problema ...
Cada registro no arquivo CSV está em uma linha diferente. Eu quero que a saída JSON seja da mesma maneira. O problema é que despeja tudo em uma longa linha gigante.
Eu tentei usar algo como for line in csvfile:
e, em seguida, executar meu código abaixo daquele com o reader = csv.DictReader( line, fieldnames)
qual faz um loop em cada linha, mas ele faz o arquivo inteiro em uma linha e, em seguida, executa o loop em todo o arquivo em outra linha ... continua até ficar sem linhas .
Alguma sugestão para corrigir isso?
Editar: Para esclarecer, atualmente eu tenho: (todos os registros na linha 1)
[{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"},{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}]
O que procuro: (2 registros em 2 linhas)
{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"}
{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}
Não cada campo individual indentado / em uma linha separada, mas cada registro em sua própria linha.
Alguns exemplos de entrada.
"John","Doe","001","Message1"
"George","Washington","002","Message2"
[{..row..},{..row..},...]
não{..row..}{..row..}..
. Ou seja, a saída parece ser uma matriz json de objetos json, não um fluxo de objetos json não conectados.Respostas:
O problema com a saída desejada é que não é um documento json válido; é um fluxo de documentos json !
Tudo bem, se for o que você precisa, mas isso significa que, para cada documento que quiser em sua saída, você terá que chamar
json.dumps
.Como a nova linha que você deseja separar seus documentos não está contida nesses documentos, você mesmo deve fornecê-la. Portanto, precisamos apenas retirar o loop da chamada para json.dump e interpor novas linhas para cada documento escrito.
fonte
DictReader
sem fornecer umfieldnames
argumento; ele então lerá a primeira linha para obter os nomes dos campos do arquivo.csvfile = open('file.csv', 'r',encoding='utf-8')
ejsonfile = open('file.json', 'w',encoding='utf-8')
Você pode usar o Pandas DataFrame para fazer isso, com o seguinte exemplo:
fonte
Peguei a resposta de @ SingleNegationElimination e a simplifiquei em um três linhas que pode ser usado em um pipeline:
fonte
Documentação de json.dumps ()
fonte
Você pode tentar isso
Editar:
Abordagem mais simples
fonte
csvmapper
para fazer isso (e talvez onde obtê-lo) em vez de algo integrado.Adicione o
indent
parâmetro ajson.dumps
Observe também que você pode simplesmente usar
json.dump
com o abertojsonfile
:fonte
Vejo que isso é antigo, mas eu precisava do código de SingleNegationElimination, no entanto, tive problemas com os dados que não continham caracteres utf-8. Eles apareceram em campos com os quais eu não estava muito preocupado, então optei por ignorá-los. No entanto, isso exigiu algum esforço. Eu sou novo no python, então, com algumas tentativas e erros, consegui fazê-lo funcionar. O código é uma cópia de SingleNegationElimination com o tratamento extra de utf-8. Tentei fazer isso com https://docs.python.org/2.7/library/csv.html, mas no final desisti. O código abaixo funcionou.
fonte
Que tal usar o Pandas para ler o arquivo csv em um DataFrame ( pd.read_csv ), em seguida, manipular as colunas se quiser (descartando-as ou atualizando os valores) e, finalmente, converter o DataFrame de volta para JSON ( pd.DataFrame.to_json ).
Observação: não verifiquei a eficiência disso, mas essa é definitivamente uma das maneiras mais fáceis de manipular e converter um csv grande em json.
fonte
Como uma pequena melhoria na resposta @MONTYHS, iterando por meio de um conjunto de nomes de campo:
fonte
fonte
DictReader
, portanto, ele adivinha os nomes dos campos da primeira linha do arquivo de entrada: John, Doe, 5, "None" em vez de "FirstName, lastname," e assim por diante ...TypeError: expected string or buffer