CSV 파일을 여러 줄 JSON으로 변환하는 방법은 무엇입니까?


98

여기 내 코드, 정말 간단한 것들이 있습니다.

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)

일부 필드 이름을 선언하고 리더는 CSV를 사용하여 파일을 읽고 파일 이름을 사용하여 파일을 JSON 형식으로 덤프합니다. 여기에 문제가 있습니다 ...

CSV 파일의 각 레코드는 다른 행에 있습니다. JSON 출력이 같은 방식이기를 원합니다. 문제는 모든 것을 하나의 거대하고 긴 줄에 버린다는 것입니다.

나는 for line in csvfile:다음 과 같은 것을 사용하고 reader = csv.DictReader( line, fieldnames)각 줄을 반복 하는 코드를 아래에서 실행 하려고 시도했지만 한 줄에서 전체 파일을 수행 한 다음 다른 줄에서 전체 파일을 반복합니다 ... 줄이 떨어질 때까지 계속됩니다. .

이 문제를 해결하기위한 제안 사항이 있습니까?

편집 : 명확히하기 위해 현재 : (1 행의 모든 ​​레코드)

[{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"},{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}]

내가 찾는 것 : (2 줄에 2 개의 레코드)

{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"}
{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}

각 개별 필드가 들여 쓰기 / 별도의 줄에있는 것이 아니라 각 레코드가 자체 줄에 있습니다.

샘플 입력.

"John","Doe","001","Message1"
"George","Washington","002","Message2"

나는 당신의 코드가 당신이 말하는 것과 정확히 일치 하는지 잘 모르겠습니다 . 그것은 생성 [{..row..},{..row..},...]하지 않아야 {..row..}{..row..}..합니다. 즉, 출력은 연결되지 않은 json 객체의 스트림이 아니라 json 객체의 json 배열 인 것처럼 보입니다.
SingleNegationElimination 2013-10-31

답변:


145

원하는 출력의 문제는 유효한 json 문서가 아니라는 것입니다. 그것은 json 문서흐름입니다 !

필요하다면 괜찮습니다.하지만 출력에서 ​​원하는 각 문서에 대해 json.dumps.

문서를 분리하려는 줄 바꿈이 해당 문서에 포함되어 있지 않으므로 직접 제공해야합니다. 따라서 json.dump에 대한 호출에서 루프를 꺼내서 작성된 각 문서에 대한 개행 문자를 삽입하면됩니다.

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')

1
완전한! 그것을 얻기 위해 약간의 마음 읽기를해야했고, 수정 / 설명에 감사드립니다. 이것이 바로 제가 찾던 것입니다.
BeanBagKing 2013-10-31

4
하지만 문제는 OUTFILE 유효한 JSON되지이다
MONTYHS

1
@MONTYHS :이 답변의 첫 번째 문장은 outfile이 json 문서가 아니라는 것을 설명합니다. 그리고 그것이 무엇인지. 이 질문을 한 사람과 다른 문제가 있습니까?
SingleNegationElimination

6
@ abhi1610 : 입력에 헤더가 필요한 DictReader경우 fieldnames인수 없이를 구성해야합니다 . 그런 다음 파일에서 필드 이름을 가져 오기 위해 첫 번째 줄을 읽습니다.
SingleNegationElimination

1
그리고 당신의 파일 인코딩을 추가하는 것이 좋다 csvfile = open('file.csv', 'r',encoding='utf-8')jsonfile = open('file.json', 'w',encoding='utf-8')
마렉 BERNAD

21

다음 예제를 통해 Pandas DataFrame을 사용하여이를 수행 할 수 있습니다.

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)

9

@SingleNegationElimination의 응답을 가져와 파이프 라인에서 사용할 수있는 세 줄로 단순화했습니다.

import csv
import json
import sys

for row in csv.DictReader(sys.stdin):
    json.dump(row, sys.stdout)
    sys.stdout.write('\n')

8
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)

json.dumps () 문서


6

당신은 이것을 시도 할 수 있습니다

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)

편집하다:

더 간단한 접근

import csvmapper

fields = ('FirstName', 'LastName', 'IDNumber', 'Messages')
parser = CSVParser('sample.csv', csvmapper.FieldMapper(fields))

converter = csvmapper.JSONConverter(parser)

print converter.doConvert(pretty=True)

3
적어도 내장 모듈이 아닌 타사 모듈을 사용하고 있다는 것을 명시 적으로 언급해야한다고 생각합니다 csvmapper.
martineau

2

indent매개 변수 추가json.dumps

 data = {'this': ['has', 'some', 'things'],
         'in': {'it': 'with', 'some': 'more'}}
 print(json.dumps(data, indent=4))

또한 json.dumpopen으로 간단히 사용할 수 있습니다 jsonfile.

json.dump(data, jsonfile)

내가 찾고있는 것이 아닙니다. 원하는 출력을 명확하고 표시하기 위해 원래 질문을 편집했습니다. 팁을 주셔서 감사합니다. 나중에 유용 할 수도 있습니다.
BeanBagKing 2013 년

2

나는 이것이 오래되었다고 생각하지만 SingleNegationElimination의 코드가 필요했지만 utf-8이 아닌 문자를 포함하는 데이터에 문제가 있습니다. 이것들은 내가 지나치게 신경 쓰지 않는 분야에 나타나서 무시하기로 결정했습니다. 그러나 그것은 약간의 노력이 필요했습니다. 나는 파이썬을 처음 접했기 때문에 시행 착오를 거쳐 작동했습니다. 이 코드는 utf-8을 추가로 처리 한 SingleNegationElimination의 복사본입니다. https://docs.python.org/2.7/library/csv.html로 시도했지만 결국 포기했습니다. 아래 코드가 작동했습니다.

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

Pandas를 사용하여 csv 파일을 DataFrame ( pd.read_csv ) 으로 읽은 다음 원하는 경우 열을 조작 (삭제 또는 값 업데이트)하고 마지막으로 DataFrame을 다시 JSON ( pd.DataFrame.to_json ) 으로 변환하는 방법은 무엇입니까 ?

참고 : 이것이 얼마나 효율적인지 확인하지 않았지만 이것은 확실히 큰 csv를 json으로 조작하고 변환하는 가장 쉬운 방법 중 하나입니다.


0

@MONTYHS 답변에 대한 약간의 개선으로 필드 이름 tup을 반복합니다.

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)

-1
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)

이것을 사용하려고하면 "KeyError : 'FirstName'"이 표시됩니다. 키가 추가되는 것 같지 않습니다. 여기서 무엇을 하려는지 정확히 모르겠지만 Wayne과 동일한 indent = 4를 사용하기 때문에 출력이 내가 찾고있는 것과 일치하지 않는다고 생각합니다. 어떤 결과를 기대해야합니까? 내가 찾고있는 내용을 명확히하기 위해 원래 게시물을 편집했습니다.
BeanBagKing 2013-10-31

키 오류는이 코드가에 헤더 인수를 전달하지 않기 때문에 발생할 가능성이 큽니다 DictReader. 따라서 입력 파일의 첫 번째 줄에서 필드 이름을 추측합니다. John, Doe, 5, "FirstName, lastname"대신 "None"및 그래서 ...
SingleNegationElimination

더 나은 옵션은 실제로 원하는 필드에 대한 CSV를 구문 분석하는 것입니다 (표시된 답변에서와 같이 순서대로뿐만 아니라)
GarciadelCastillo

내가 말하는 오류가TypeError: expected string or buffer
CodyBugstein
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.