[python] JSON을 CSV로 변환하려면 어떻게해야합니까?

CSV 파일로 변환하려는 JSON 파일이 있습니다. 파이썬으로 어떻게 이것을 할 수 있습니까?

나는 시도했다 :

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

그러나 작동하지 않았습니다. Django를 사용하고 있으며 수신 된 오류는 다음과 같습니다.

file' object has no attribute 'writerow'

그런 다음 다음을 시도했습니다.

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

그런 다음 오류가 발생합니다.

sequence expected

샘플 json 파일 :

[{
        "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
        }
    }
]



답변

먼저 JSON에 중첩 된 객체가 있으므로 일반적으로 CSV로 직접 변환 할 수 없습니다. 이를 다음과 같이 변경해야합니다.

{
    "pk": 22,
    "model": "auth.permission",
    "codename": "add_logentry",
    "content_type": 8,
    "name": "Can add log entry"
},
......]

그로부터 CSV를 생성하는 코드는 다음과 같습니다.

import csv
import json

x = """[
    {
        "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
        }
    }
]"""

x = json.loads(x)

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

# Write CSV Header, If you dont need that, remove this line
f.writerow(["pk", "model", "codename", "name", "content_type"])

for x in x:
    f.writerow([x["pk"],
                x["model"],
                x["fields"]["codename"],
                x["fields"]["name"],
                x["fields"]["content_type"]])

다음과 같이 출력됩니다.

pk,model,codename,name,content_type
22,auth.permission,add_logentry,Can add log entry,8
23,auth.permission,change_logentry,Can change log entry,8
24,auth.permission,delete_logentry,Can delete log entry,8


답변

pandas 도서관 , 이 두 명령을 사용하는 것만 큼 쉽습니다!

pandas.read_json()

JSON 문자열을 pandas 객체 (시리즈 또는 데이터 프레임)로 변환합니다. 그런 다음 결과가 다음과 같이 저장되었다고 가정합니다 df.

df.to_csv()

문자열을 반환하거나 csv 파일에 직접 쓸 수 있습니다.

이전 답변의 자세한 내용을 바탕으로 팬더에게 지름길을 준 것에 감사드립니다.


답변

JSON 파일이 사전 목록으로 디코딩된다고 가정합니다. 먼저 JSON 객체를 평평하게하는 함수가 필요합니다.

def flattenjson( b, delim ):
    val = {}
    for i in b.keys():
        if isinstance( b[i], dict ):
            get = flattenjson( b[i], delim )
            for j in get.keys():
                val[ i + delim + j ] = get[j]
        else:
            val[i] = b[i]

    return val

이 스 니펫을 JSON 객체에서 실행 한 결과 :

flattenjson( {
    "pk": 22, 
    "model": "auth.permission", 
    "fields": {
      "codename": "add_message", 
      "name": "Can add message", 
      "content_type": 8
    }
  }, "__" )

이다

{
    "pk": 22, 
    "model": "auth.permission', 
    "fields__codename": "add_message", 
    "fields__name": "Can add message", 
    "fields__content_type": 8
}

JSON 객체의 입력 배열에서 각 dict에이 함수를 적용한 후 :

input = map( lambda x: flattenjson( x, "__" ), input )

관련 열 이름 찾기 :

columns = [ x for row in input for x in row.keys() ]
columns = list( set( columns ) )

csv 모듈을 통해 이것을 실행하는 것은 어렵지 않습니다.

with open( fname, 'wb' ) as out_file:
    csv_w = csv.writer( out_file )
    csv_w.writerow( columns )

    for i_r in input:
        csv_w.writerow( map( lambda x: i_r.get( x, "" ), columns ) )

이게 도움이 되길 바란다!


답변

JSON은 다양한 데이터 구조를 나타낼 수 있습니다. JS “개체”는 대략 파이썬 dict (문자열 키 포함), JS “배열”은 대략 파이썬 목록과 비슷하며 마지막 ” leaf “요소는 숫자 또는 문자열입니다.

CSV는 본질적으로 2 차원 테이블 만 나타낼 수 있습니다. 선택적으로 첫 번째 “헤더”행 (예 : “열 이름”)을 사용하면 테이블을 일반 해석 대신 딕트 목록으로 해석 할 수 있습니다. 리스트 (다시 말해서 “리프”요소는 숫자 나 문자열이 될 수 있습니다).

따라서 일반적인 경우 임의의 JSON 구조를 CSV로 변환 할 수 없습니다. 몇 가지 특별한 경우 (더 이상 중첩이없는 배열의 배열; 모두 정확히 동일한 키를 가진 객체의 배열)가 가능합니다. 문제에 어떤 특별한 경우가 적용됩니까? 솔루션의 세부 사항은 가지고있는 특수 사례에 따라 다릅니다. 어떤 것이 적용되는지 언급조차하지 않는다는 놀라운 사실을 감안할 때, 나는 당신이 제약을 고려하지 않았을 수도 있고, 실제로 사용 가능한 사례도 적용되지 않을 수도 있으며, 문제를 해결할 수 없다고 생각합니다. 그러나 명확히하십시오!


답변

플랫 객체 의 json 목록 을 csv로 변환하는 일반적인 솔루션입니다 .

input.json 파일을 명령 행에서 첫 번째 인수로 전달하십시오.

import csv, json, sys

input = open(sys.argv[1])
data = json.load(input)
input.close()

output = csv.writer(sys.stdout)

output.writerow(data[0].keys())  # header row

for row in data:
    output.writerow(row.values())


답변

이 코드는 JSON 데이터가라는 파일에 있다고 가정하면 효과적입니다 data.json.

import json
import csv

with open("data.json") as file:
    data = json.load(file)

with open("data.csv", "w") as file:
    csv_file = csv.writer(file)
    for item in data:
        fields = list(item['fields'].values())
        csv_file.writerow([item['pk'], item['model']] + fields)


답변

사용하기 쉽고 csv.DictWriter()자세한 구현 방법은 다음과 같습니다.

def read_json(filename):
    return json.loads(open(filename).read())
def write_csv(data,filename):
    with open(filename, 'w+') as outf:
        writer = csv.DictWriter(outf, data[0].keys())
        writer.writeheader()
        for row in data:
            writer.writerow(row)
# implement
write_csv(read_json('test.json'), 'output.csv')

이것은 모든 JSON 객체가 동일한 필드를 가지고 있다고 가정합니다.

여기 도움이 될만한 참고 자료 가 있습니다.