Oto mój kod, naprawdę proste rzeczy ...
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)
Zadeklaruj niektóre nazwy pól, czytnik używa CSV do odczytania pliku, a nazwy plików do zrzucenia pliku do formatu JSON. Oto problem ...
Każdy rekord w pliku CSV znajduje się w innym wierszu. Chcę, aby dane wyjściowe JSON były takie same. Problem w tym, że zrzuca to wszystko na jedną wielką, długą linię.
Próbowałem użyć czegoś podobnego, for line in csvfile:
a następnie uruchomić mój kod poniżej tego, z reader = csv.DictReader( line, fieldnames)
którym pętla przechodzi przez każdą linię, ale robi cały plik w jednej linii, a następnie przechodzi przez cały plik w innej linii ... kontynuuje, dopóki nie skończą się linie .
Jakieś sugestie, jak to naprawić?
Edycja: Aby wyjaśnić, obecnie mam: (każdy rekord w linii 1)
[{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"},{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}]
Czego szukam: (2 rekordy w 2 liniach)
{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"}
{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}
Nie każde pole jest wcięte / w osobnym wierszu, ale każdy rekord w osobnym wierszu.
Niektóre przykładowe dane wejściowe.
"John","Doe","001","Message1"
"George","Washington","002","Message2"
[{..row..},{..row..},...]
nie{..row..}{..row..}..
. Oznacza to, że dane wyjściowe wyglądają na tablicę json obiektów json, a nie strumień niepołączonych obiektów json.Odpowiedzi:
Problem z żądanym wyjściem polega na tym, że nie jest to prawidłowy dokument json; to strumień dokumentów json !
W porządku, jeśli tego potrzebujesz, ale oznacza to, że dla każdego dokumentu, który chcesz umieścić w wyniku, będziesz musiał zadzwonić
json.dumps
.Ponieważ nowa linia, którą chcesz oddzielić dokumenty, nie jest zawarta w tych dokumentach, jesteś na haku, aby dostarczyć go samodzielnie. Musimy więc po prostu wyciągnąć pętlę z wywołania json.dump i wstawić nowe linie dla każdego napisanego dokumentu.
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')
źródło
DictReader
bez podawaniafieldnames
argumentu; odczyta wtedy pierwszą linię, aby pobrać nazwy pól z pliku.csvfile = open('file.csv', 'r',encoding='utf-8')
ijsonfile = open('file.json', 'w',encoding='utf-8')
Aby to osiągnąć, możesz użyć Pandas DataFrame, korzystając z następującego przykładu:
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)
źródło
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)
Dokumentacja json.dumps ()
źródło
Wziąłem odpowiedź @ SingleNegationElimination i uprościłem ją do trzyliniówki, której można używać w potoku:
import csv import json import sys for row in csv.DictReader(sys.stdin): json.dump(row, sys.stdout) sys.stdout.write('\n')
źródło
Możesz tego spróbować
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)
Edytować:
Prostsze podejście
import csvmapper fields = ('FirstName', 'LastName', 'IDNumber', 'Messages') parser = CSVParser('sample.csv', csvmapper.FieldMapper(fields)) converter = csvmapper.JSONConverter(parser) print converter.doConvert(pretty=True)
źródło
csvmapper
, aby to zrobić (i być może skąd go wziąć), w przeciwieństwie do czegoś wbudowanego.Dodaj
indent
parametr dojson.dumps
data = {'this': ['has', 'some', 'things'], 'in': {'it': 'with', 'some': 'more'}} print(json.dumps(data, indent=4))
Pamiętaj również, że możesz po prostu użyć
json.dump
z otwartymjsonfile
:źródło
Widzę, że to jest stare, ale potrzebowałem kodu z SingleNegationElimination, ale miałem problem z danymi zawierającymi znaki inne niż utf-8. Pojawiły się one w dziedzinach, którymi się specjalnie nie przejmowałem, więc zdecydowałem się je zignorować. Jednak wymagało to pewnego wysiłku. Jestem nowy w Pythonie, więc dzięki kilku próbom i błędom udało mi się go uruchomić. Kod jest kopią SingleNegationElimination z dodatkową obsługą utf-8. Próbowałem to zrobić z https://docs.python.org/2.7/library/csv.html, ale w końcu się poddałem. Poniższy kod zadziałał.
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
źródło
Co powiesz na użycie Pandas do odczytania pliku csv do DataFrame ( pd.read_csv ), a następnie manipulowanie kolumnami, jeśli chcesz (upuszczanie ich lub aktualizowanie wartości) i wreszcie przekonwertowanie DataFrame z powrotem na JSON ( pd.DataFrame.to_json ).
Uwaga: nie sprawdziłem, jak wydajne będzie to, ale jest to zdecydowanie jeden z najłatwiejszych sposobów manipulowania i konwertowania dużego pliku csv na json.
źródło
Jako niewielkie ulepszenie odpowiedzi @MONTYHS, iteracja przez krotkę nazw pól:
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)
źródło
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)
źródło
DictReader
, więc zgaduje nazwy pól z pierwszego wiersza pliku wejściowego: Jan, Kowalski, 5, „Brak” zamiast „Imię, nazwisko” i tak dalej ...TypeError: expected string or buffer