2014-02-26 4 views
0

나는 다음 줄을 내가 헤더와 CSV 읽을 수있는 파일로 모든 라인을 변환 할에서 CSV로 변환 하시겠습니까?

{"status":"OK","message":"OK","data":[{"type":"addressAccessType","addressAccessId":"0a3f508f-e7c8-32b8-e044-0003ba298018","municipalityCode":"0766","municipalityName":"Hedensted","streetCode":"0072","streetName":"Værnegården","streetBuildingIdentifier":"13","mailDeliverySublocationIdentifier":"","districtSubDivisionIdentifier":"","postCodeIdentifier":"8000","districtName":"Århus","presentationString":"Værnegården 13, 8000 Århus","addressSpecificCount":1,"validCoordinates":true,"geometryWkt":"POINT(553564 6179299)","x":553564,"y":6179299}]} 

로 파일을 가지고있다. 다음과 같이

status,message,data,addressAccessId,municipalityCode,municipalityName,streetCode,streetName,streetBuildingIdentifier,mailDeliverySublocationIdentifier,districtSubDivisionIdentifier,postCodeIdentifier,districtName,presentationString,addressSpecificCount,validCoordinates,geometryWkt,x,y 
OK,OK,data:type,addressAccessType,0a3f508f-e7c8-32b8-e044-0003ba298018,0766,Hedensted,0072,Værnegården,13,,,8000,Århus,Værnegården 13, 8000 Århus,1,true,POINT553564 6179299,553564,6179299 

어떻게 수행 할 수 있습니까? 코드와 설명은 대단히 환영합니다. 지금까지 내가 (교체) 및 번역,

x = json.loads(x) 

f = csv.writer(open('test.csv', 'wb+')) 

# Write CSV Header, If you dont need that, remove this line 
f.writerow(['status', 'message', 'type', 'addressAccessId', 'municipalityCode','municipalityName','streetCode','streetName','streetBuildingIdentifier','mailDeliverySublocationIdentifier','districtSubDivisionIdentifier','postCodeIdentifier','districtName','presentationString','addressSpecificCount','validCoordinates','geometryWkt','x','y']) 


for x in x: 
    f.writerow([x['status'], 
       x['message'], 
       x['data']['type'], 
       x['data']['addressAccessId'], 
       x['data']['municipalityCode'], 
       x['data']['municipalityName'], 
       x['data']['streetCode'], 
       x['data']['streetName'], 
       x['data']['streetBuildingIdentifier'], 
       x['data']['mailDeliverySublocationIdentifier'], 
       x['data']['districtSubDivisionIdentifier'], 
       x['data']['postCodeIdentifier'], 
       x['data']['districtName'], 
       x['data']['presentationString'], 
       x['data']['addressSpecificCount'], 
       x['data']['validCoordinates'], 
       x['data']['geometryWkt'], 
       x['data']['x'], 
       x['data']['y']]) 

내가 통해 보았다 DictWriter를 포함하여 다른 솔루션을 많이 시도) How can I convert JSON to CSV? :(이 예에서 다음과 같이 올라와있다 무엇()을 제거합니다 개개인은 아직 그 필요를 충족시킬 줄을 바꾸지 못했습니다. 새 파일로 출력되는 필드를 선택하고 x 및 y를 새 좌표계로 변환 할 수 있습니다. 하지만 지금은 그냥 위의 줄을 CSV 파일로 구문 분석하려고합니다. 누구든지 코드와 코드에 대한 설명을 제공 할 수 있습니까? 시간 내 주셔서 대단히 감사합니다. 다음은

data 키 사전의 목록를 보유하고 있음을 내 addresses.txt

{"status":"OK","message":"OK","data":[{"type":"addressAccessType","addressAccessId":"0a3f5081-e039-32b8-e044-0003ba298018","municipalityCode":"0265","municipalityName":"Roskilde","streetCode":"0831","streetName":"Brønsager","streetBuildingIdentifier":"69","mailDeliverySublocationIdentifier":"","districtSubDivisionIdentifier":"Svogerslev","postCodeIdentifier":"4000","districtName":"Roskilde","presentationString":"Brønsager 69, 4000 Roskilde","addressSpecificCount":1,"validCoordinates":true,"geometryWkt":"POINT(690026 6169309)","x":690026,"y":6169309}]} 
    {"status":"OK","message":"OK","data":[{"type":"addressAccessType","addressAccessId":"0a3f5089-ecab-32b8-e044-0003ba298018","municipalityCode":"0461","municipalityName":"Odense","streetCode":"9505","streetName":"Vægtens Kvarter","streetBuildingIdentifier":"271","mailDeliverySublocationIdentifier":"","districtSubDivisionIdentifier":"Holluf Pile","postCodeIdentifier":"5220","districtName":"Odense SØ","presentationString":"Vægtens Kvarter 271, 5220 Odense SØ","addressSpecificCount":1,"validCoordinates":true,"geometryWkt":"POINT(592191 6135829)","x":592191,"y":6135829}]} 
    {"status":"OK","message":"OK","data":[{"type":"addressAccessType","addressAccessId":"0a3f507c-adc3-32b8-e044-0003ba298018","municipalityCode":"0165","municipalityName":"Albertslund","streetCode":"0445","streetName":"Skyttehusene","streetBuildingIdentifier":"33","mailDeliverySublocationIdentifier":"","districtSubDivisionIdentifier":"","postCodeIdentifier":"2620","districtName":"Albertslund","presentationString":"Skyttehusene 33, 2620 Albertslund","addressSpecificCount":1,"validCoordinates":true,"geometryWkt":"POINT(711079 6174741)","x":711079,"y":6174741}]} 
    {"status":"OK","message":"OK","data":[{"type":"addressAccessType","addressAccessId":"0a3f509c-7f57-32b8-e044-0003ba298018","municipalityCode":"0851","municipalityName":"Aalborg","streetCode":"5205","streetName":"Løvstikkevej","streetBuildingIdentifier":"36","mailDeliverySublocationIdentifier":"","districtSubDivisionIdentifier":"","postCodeIdentifier":"9000","districtName":"Aalborg","presentationString":"Løvstikkevej 36, 9000 Aalborg","addressSpecificCount":1,"validCoordinates":true,"geometryWkt":"POINT(552407 6322490)","x":552407,"y":6322490}]} 
    {"status":"OK","message":"OK","data":[{"type":"addressAccessType","addressAccessId":"0a3f5098-32a6-32b8-e044-0003ba298018","municipalityCode":"0779","municipalityName":"Skive","streetCode":"0462","streetName":"Landevejen","streetBuildingIdentifier":"52","mailDeliverySublocationIdentifier":"","districtSubDivisionIdentifier":"Håsum","postCodeIdentifier":"7860","districtName":"Spøttrup","presentationString":"Landevejen 52, 7860 Spøttrup","addressSpecificCount":1,"validCoordinates":true,"geometryWkt":"POINT(491515 6269739)","x":491515,"y":6269739}]} 
+1

리스트를'x'라고도 부를 때 반복 변수에'x'를 재사용하지 않겠습니다. –

답변

3

주의의 처음 몇 줄 수 있습니다. x['data']['type']은 작동하지 않지만 x['data'][0]['type']이됩니다. 그러나 그 목록에 하나 이상의 사전이있을 수 있습니다. CSV 행을 x['data'] 사전으로 가정합니다.

다음으로 모든 줄에 UTF-8 BOM 이있는 것 같습니다.; 어떤 것을 써도 UTF-8 인코딩이 올바르게 사용되지 않았습니다. 첫 번째 3자인이 마커를 제거해야합니다.

마지막으로 JSON 문자열은 항상 유니 코드 데이터이므로 비 ASCII 문자가 데이터에 포함되어 있으므로 데이터를 CSV writer 객체로 전달하기 전에 다시 바이트 스트링을 인코딩해야합니다.

내가 필드 이름의 미리 정의 된 목록과 함께, 여기 csv.DictWriter을 사용하십시오

다음 statusmessage으로,

import codecs 
import csv 
import json 

fields = [ 
    'status', 'message', 'type', 'addressAccessId', 'municipalityCode', 
    'municipalityName', 'streetCode', 'streetName', 'streetBuildingIdentifier', 
    'mailDeliverySublocationIdentifier', 'districtSubDivisionIdentifier', 
    'postCodeIdentifier', 'districtName', 'presentationString', 'addressSpecificCount', 
    'validCoordinates', 'geometryWkt', 'x', 'y'] 


with open('test.csv', 'wb') as csvfile, open('jsonfile', 'r') as jsonfile: 
    writer = csv.DictWriter(csvfile, fields) 
    writer.writeheader() 

    for line in jsonfile: 
     if line.startswith(codecs.BOM_UTF8): 
      line = line[3:] 
     entry = json.loads(line) 
     for item in entry['data']: 
      row = dict(item, status=entry['status'], message=entry['message']) 
      row = {k.encode('utf8'): unicode(v).encode('utf8') for k, v in row.iteritems()} 
      writer.writerow(row) 

row 사전은 기본적으로 entry['data'] 목록에서 사전의 각각의 사본입니다 키는 별도로 복사됩니다. 이로 인해 row은 대신에 일괄 사전이됩니다.

입력 파일을 한 줄씩 읽습니다. 각 줄마다 별도의 JSON 항목이 포함되어 있습니다.

+0

'for' 루프에'writer.writerow (row)'를 넣으시겠습니까? – colcarroll

+0

자세한 답변을 주셔서 감사합니다. 확실히 도움이됩니다. 당신은 내가 원하는 데이터가'x [data]'에있는 여러 줄의 파일을 가지고 있다고 가정하는 것이 옳습니다. 그러나, 당신이 코드를하려고하면 다음과 같은 오류가 발생합니다. 'ValueError : JSON 객체를 디코딩 할 수 없습니다.'라는 메시지는 json-lines이 포함 된 파일이거나 json이 유효하지 않을 수 있습니다. – Philip

+0

@ JLLagrange : 실제로 할 수 있습니다. –

0

cvs.DictWriter()로 출력 파일을 열고 지정한대로 출력 헤더 필드를 정의하십시오. extrasaction = 'ignore'및 restval = ''을 옵션으로 사용하십시오.

비슷한 질문을했기 때문에 큰 파일을 처리하는 데 도움이 필요하면 Opening A large JSON file in Python with no newlines for csv conversion Python 2.6.6을보십시오. 제가 링크 된 질문을 살펴보십시오.

적절한 루프를 사용하여 JSON에서 유사한 유형의 시스템을 구축합니다.예

이 인수로 currdata 가진 함수이며, 입력 인자로서 X [ '데이터'] [행] 불려

def parse_row(currdata): 
    outx = {} 
    # currdata is defined earlier to point to the x['data'] dictionary 
    for eachx in currdata: 
    outx[eachx] = currdata[eachx] 
    return outx 

한다.

rows = len(x['data']) 
for row in range(rows): 
    outx = parse_row(x['data'][row]) 
    # process the row and create output 

이렇게하면 구문 분석을 올바르게 설정할 수 있습니다. 나는이 코드에 실제 코드를 복사 할 수는 없지만 해결책을 제시해야한다.