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


184

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
        }
    }
]

1
csv_file.writerow (item)에는 항목이 간단한 문자열 또는 숫자 목록이어야합니다. 각 json 객체를 { "pk": 22, "model": "auth.permission"}과 같이 간단한 목록으로 변환 해보십시오. [22, auth.permission].
Suppressingfire

1
이에 대한 간단한 접근 방식은 다음 jq과 같이 설명되어 있습니다. stackoverflow.com/questions/32960857/…
Micah Elliott

타사 대안 : json-csv.com (일회성 변환의 경우) 또는 json-csv.com/api 를 사용하여 Python으로 자동화 더 복잡한 JSON 구조를위한 간단한 솔루션입니다.
Stack Man

답변:


129

먼저 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

2
이 작품 그러나 유감 전에 내가하지 하드 코드 나는 것은 더 나은 ID 내가 f.writerow를 사용할 수있는 뭔가를 얻을 수 (A)와 a는 내가 전에 감사하기 전에 선언 몇 가지 variabel입니다
little_fish

나에게 이것은 거의 완벽하게 작동합니다. 내 보낸 CSV에서 일부 필드는 [u'및 로 둘러싸 ']입니다. (비 사후 처리) 해결 방법은 무엇입니까? 하나가 있다면 ... :)
Dror

3
아래에서는 하드 코딩없이 더 일반적으로 수행하는 방법을 보여주었습니다.
Alec McGail

4
이봐, 난이 시도했지만 내가 받고 있어요 TypeError: a bytes-like object is required, not 'str'에서f.writerow(['pk', 'model', 'codename', 'name', 'content_type'])
디트 야 하리 하란

8
csv 파일을 여는 python3 행 변경f = csv.writer(open("test.csv", "w", newline=''))
PiotrK

118

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

pandas.read_json()

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

df.to_csv()

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

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


1
이것은 환상적인 답변입니다 (+1)-매우 간단하고 .to_csv()실제로 강력합니다 (예 : 무료 열 필터링). 팬더를 배워야합니다.
WoJ

3
지적 했듯이이 답변은이 질문의 데이터에는 작동하지 않습니다. orient='records'를 설정해야하지만의 각 행 fields은 여전히 dict이며 OP는 요청하지 않습니다.
Trenton McKinney

90

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

이게 도움이 되길 바란다!


Python 3.6을 사용하여 마지막 루프가 작동하도록 평탄화 된 JSON 목록을 만들어야했습니다. "input = list (map (lambda x : flattenjson (x,"__ "), input))"). 왜 iterable이 충분하지 않은지 이해하지 못합니다. 내 데이터가 UTF8을 사용하므로 출력 파일을 열 때 인코딩을 지정해야했습니다. 확실히 도움이되었습니다. 감사합니다!
Alexis R

알렉 감사합니다! 여러 수준의 중첩 작업을 수행하도록 수정했습니다. stackoverflow.com/a/57228641/473201
phreakhead

35

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

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

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


31

플랫 객체 의 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())

2
중요한 주석-이 코드는 첫 번째 행의 필드에서 열 / 헤더를 유추합니다. json 데이터에 '들쭉날쭉 한'열이있는 경우, 즉 row1에 5 개의 열이 있지만 row2에 6 개의 열이 있다고 가정하면 모든 열의 총 집합을 가져 와서 헤더로 사용하려면 데이터를 먼저 전달해야합니다.
Mike Repass

내가 가지고있는 데이터를 사용하면 필요한 솔루션의 큰 부분을 차지했습니다 .JSON이 들쭉날쭉하지 않기 때문에 기존 스크립트 내에서이를 실행했기 때문에 약간의 출력 조정으로 훌륭하게 작동했습니다.
MichaelF

1
이 코드는 또한 값이 헤더 행의 키와 동일한 순서로 출력된다고 가정합니다. 그것이 운이 좋았을 수도 있지만, 결코 보장되지는 않습니다.
RyanHennig

인코딩 오류가 발생했습니다. UTF-8에 인코딩을 추가하는 방법에 대한 아이디어가 있습니까?
Elad Tabak

25

이 코드는 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)

1
흠, 아니- csv_file.writerow( f.writerow물론, 오타가 없다고 가정합니다!) dict가 아닌 시퀀스를 원합니다. 예에서 각 항목은 dict입니다. 내 대답에서 확인한 것처럼 JSON 파일에는 배열 배열이있는 다른 특별한 경우에 효과적입니다. 해결하려는 것처럼 보이는 특수한 경우 인 객체 배열에는 작동하지 않습니다 (필요한 경우 csv.DictWriter-필드 이름을 추출하고 인스턴스화하기 위해 순서를 결정해야 함) !-).
Alex Martelli

@DanLoewenherz 최신 Python 버전에서는 작동하지 않습니다. TypeError : 목록 ( "dict_values"가 아님) 만 목록에 연결할 수 있습니다
Apolo Radomer

18

사용하기 쉽고 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 객체가 동일한 필드를 가지고 있다고 가정합니다.

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


이 링크가 질문에 대답 할 수 있지만 여기에 답변의 필수 부분을 포함시키고 참조 할 수있는 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않을 수 있습니다. - 리뷰에서
Mathieu

3
@purplepsycho 나는이 답변을 downvote와 함께 찾았습니다. 링크 만 있어야합니다. 링크 만 알지 못하는 새로운 사용자는 정답이 아닙니다. 나는 공감했다; 새로운 사용자가 계속해서 커뮤니티에 참여하도록 독려하기를 원하십니까?
Mawg는 모니카

6

Dan이 제안한 솔루션에 문제가 있었지만 이것이 나를 위해 일했습니다.

import json
import csv 

f = open('test.json')
data = json.load(f)
f.close()

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

for item in data:
  f.writerow([item['pk'], item['model']] + item['fields'].values())

"test.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 } }
]

샘플 데이터에서 프로그램을 시도 할 때 오류가 발생했습니다. C : \ curl> python json2csv.py Traceback (가장 최근 호출) : <module> f.writerow ([item [ 'pk '], item ['model ']] + item ['fields ']. values ​​()) TypeError : 목록 ( "dict_values"아님) 만 목록에 연결할 수 있음
Mian Asbat Ahmad

Python 2.7.9에서 지금 다시 시도해 보았습니다.
Amanda

6

사용 json_normalize에서 pandas:

  • 제공된 파일에서 이름이 지정된 파일에 test.json
  • encoding='utf-8' 필요하지 않을 수 있습니다.
  • 다음 코드는 pathlib라이브러리를 활용 합니다.
    • .open ~의 방법이다 pathlib
    • Windows 이외의 경로에서도 작동
import pandas as pd
# As of Pandas 1.01, json_normalize as pandas.io.json.json_normalize is deprecated and is now exposed in the top-level namespace.
# from pandas.io.json import json_normalize
from pathlib import Path
import json

# set path to file
p = Path(r'c:\some_path_to_file\test.json')

# read json
with p.open('r', encoding='utf-8') as f:
    data = json.loads(f.read())

# create dataframe
df = pd.json_normalize(data)

# dataframe view
 pk            model  fields.codename           fields.name  fields.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
  4  auth.permission        add_group         Can add group                    2
 10  auth.permission      add_message       Can add message                    4

# save to csv
df.to_csv('test.csv', index=False, encoding='utf-8')

CSV 출력 :

pk,model,fields.codename,fields.name,fields.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
4,auth.permission,add_group,Can add group,2
10,auth.permission,add_message,Can add message,4

더 많이 중첩 된 JSON 객체에 대한 기타 리소스 :


4

이전 답변에서 언급했듯이 json을 csv로 변환하는 데 어려움은 json 파일이 중첩 된 사전을 포함 할 수 있으므로 2D 데이터 구조 인 csv를 다차원 데이터 구조로 만들 수 있기 때문입니다. 그러나 다차원 구조를 csv로 전환하는 좋은 방법은 기본 키와 함께 여러 csv를 사용하는 것입니다.

예에서 첫 번째 csv 출력에는 열 "pk", "model", "fields"열이 있습니다. "pk"및 "model"의 값은 쉽게 얻을 수 있지만 "fields"열에는 사전이 포함되어 있기 때문에 자체 csv 여야하며 "codename"이 기본 키로 표시되므로 입력으로 사용할 수 있습니다. "필드"가 첫 csv를 완료합니다. 두 번째 csv에는 "css"열의 사전이 포함되어 있으며 코드 이름이 기본 키로 사용되어 2 csvs를 묶는 데 사용할 수 있습니다.

다음은 중첩 사전을 2 csvs로 변환하는 json 파일에 대한 솔루션입니다.

import csv
import json

def readAndWrite(inputFileName, primaryKey=""):
    input = open(inputFileName+".json")
    data = json.load(input)
    input.close()

    header = set()

    if primaryKey != "":
        outputFileName = inputFileName+"-"+primaryKey
        if inputFileName == "data":
            for i in data:
                for j in i["fields"].keys():
                    if j not in header:
                        header.add(j)
    else:
        outputFileName = inputFileName
        for i in data:
            for j in i.keys():
                if j not in header:
                    header.add(j)

    with open(outputFileName+".csv", 'wb') as output_file:
        fieldnames = list(header)
        writer = csv.DictWriter(output_file, fieldnames, delimiter=',', quotechar='"')
        writer.writeheader()
        for x in data:
            row_value = {}
            if primaryKey == "":
                for y in x.keys():
                    yValue = x.get(y)
                    if type(yValue) == int or type(yValue) == bool or type(yValue) == float or type(yValue) == list:
                        row_value[y] = str(yValue).encode('utf8')
                    elif type(yValue) != dict:
                        row_value[y] = yValue.encode('utf8')
                    else:
                        if inputFileName == "data":
                            row_value[y] = yValue["codename"].encode('utf8')
                            readAndWrite(inputFileName, primaryKey="codename")
                writer.writerow(row_value)
            elif primaryKey == "codename":
                for y in x["fields"].keys():
                    yValue = x["fields"].get(y)
                    if type(yValue) == int or type(yValue) == bool or type(yValue) == float or type(yValue) == list:
                        row_value[y] = str(yValue).encode('utf8')
                    elif type(yValue) != dict:
                        row_value[y] = yValue.encode('utf8')
                writer.writerow(row_value)

readAndWrite("data")

4

나는이 질문을 한 지 오래 된 것을 알고 있지만 다른 사람들의 답변에 추가하고 솔루션을 매우 간결하게 설명하는 블로그 게시물을 공유 할 수 있다고 생각했습니다.

여기 링크가 있습니다

쓸 파일을 엽니 다

employ_data = open('/tmp/EmployData.csv', 'w')

CSV 기록기 개체 만들기

csvwriter = csv.writer(employ_data)
count = 0
for emp in emp_data:
      if count == 0:
             header = emp.keys()
             csvwriter.writerow(header)
             count += 1
      csvwriter.writerow(emp.values())

내용을 저장하기 위해 파일을 닫아야합니다

employ_data.close()

3

그것을하는 것이 현명한 방법은 아니지만 같은 문제가 있었고 이것은 나를 위해 일했습니다.

import csv

f = open('data.json')
data = json.load(f)
f.close()

new_data = []

for i in data:
   flat = {}
   names = i.keys()
   for n in names:
      try:
         if len(i[n].keys()) > 0:
            for ii in i[n].keys():
               flat[n+"_"+ii] = i[n][ii]
      except:
         flat[n] = i[n]
   new_data.append(flat)  

f = open(filename, "r")
writer = csv.DictWriter(f, new_data[0].keys())
writer.writeheader()
for row in new_data:
   writer.writerow(row)
f.close()

3

Alec의 대답 은 훌륭하지만 여러 수준의 중첩이있는 경우 작동하지 않습니다. 다음은 여러 수준의 중첩을 지원하는 수정 된 버전입니다. 또한 중첩 된 객체가 이미 자체 키 (예 : Firebase Analytics / BigTable / BigQuery 데이터)를 지정하는 경우 헤더 이름을 약간 더 멋지게 만듭니다.

"""Converts JSON with nested fields into a flattened CSV file.
"""

import sys
import json
import csv
import os

import jsonlines

from orderedset import OrderedSet

# from https://stackoverflow.com/a/28246154/473201
def flattenjson( b, prefix='', delim='/', val=None ):
  if val == None:
    val = {}

  if isinstance( b, dict ):
    for j in b.keys():
      flattenjson(b[j], prefix + delim + j, delim, val)
  elif isinstance( b, list ):
    get = b
    for j in range(len(get)):
      key = str(j)

      # If the nested data contains its own key, use that as the header instead.
      if isinstance( get[j], dict ):
        if 'key' in get[j]:
          key = get[j]['key']

      flattenjson(get[j], prefix + delim + key, delim, val)
  else:
    val[prefix] = b

  return val

def main(argv):
  if len(argv) < 2:
    raise Error('Please specify a JSON file to parse')

  filename = argv[1]
  allRows = []
  fieldnames = OrderedSet()
  with jsonlines.open(filename) as reader:
    for obj in reader:
      #print obj
      flattened = flattenjson(obj)
      #print 'keys: %s' % flattened.keys()
      fieldnames.update(flattened.keys())
      allRows.append(flattened)

  outfilename = filename + '.csv'
  with open(outfilename, 'w') as file:
    csvwriter = csv.DictWriter(file, fieldnames=fieldnames)
    csvwriter.writeheader()
    for obj in allRows:
      csvwriter.writerow(obj)



if __name__ == '__main__':
  main(sys.argv)

2

이것은 비교적 잘 작동합니다. json을 평평하게하여 csv 파일에 씁니다. 중첩 요소가 관리됩니다 :)

그것은 파이썬 3입니다

import json

o = json.loads('your json string') # Be careful, o must be a list, each of its objects will make a line of the csv.

def flatten(o, k='/'):
    global l, c_line
    if isinstance(o, dict):
        for key, value in o.items():
            flatten(value, k + '/' + key)
    elif isinstance(o, list):
        for ov in o:
            flatten(ov, '')
    elif isinstance(o, str):
        o = o.replace('\r',' ').replace('\n',' ').replace(';', ',')
        if not k in l:
            l[k]={}
        l[k][c_line]=o

def render_csv(l):
    ftime = True

    for i in range(100): #len(l[list(l.keys())[0]])
        for k in l:
            if ftime :
                print('%s;' % k, end='')
                continue
            v = l[k]
            try:
                print('%s;' % v[i], end='')
            except:
                print(';', end='')
        print()
        ftime = False
        i = 0

def json_to_csv(object_list):
    global l, c_line
    l = {}
    c_line = 0
    for ov in object_list : # Assumes json is a list of objects
        flatten(ov)
        c_line += 1
    render_csv(l)

json_to_csv(o)

즐겨.


.csv 파일이 생성되지 않고 대신 csv 텍스트가 콘솔로 출력되었습니다. 또한 json.loads작동하지 않았기 때문에와 함께 작동 json.load하여 목록 객체를 멋지게 생성했습니다. 셋째, 중첩 요소가 손실되었습니다.
ZygD

2

이것을 해결하는 간단한 방법 :

json_to_csv.py와 같은 새 Python 파일을 작성하십시오.

이 코드를 추가하십시오 :

import csv, json, sys
#if you are not using utf-8 files, remove the next line
sys.setdefaultencoding("UTF-8")
#check if you pass the input file and output file
if sys.argv[1] is not None and sys.argv[2] is not None:

    fileInput = sys.argv[1]
    fileOutput = sys.argv[2]

    inputFile = open(fileInput)
    outputFile = open(fileOutput, 'w')
    data = json.load(inputFile)
    inputFile.close()

    output = csv.writer(outputFile)

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

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

이 코드를 추가 한 후 파일을 저장하고 터미널에서 실행하십시오.

python json_to_csv.py input.txt output.csv

도움이 되었기를 바랍니다.

안녕!


1
이 샘플은 매력처럼 작동합니다! 공유해 주셔서 감사
합니다이

2

놀랍게도, 여기까지 게시 된 답변 중 모든 가능한 시나리오 (예 : 중첩 된 dicts, 중첩 된 목록, 없음 값 등)를 올바르게 처리하지 못했습니다.

이 솔루션은 모든 시나리오에서 작동해야합니다.

def flatten_json(json):
    def process_value(keys, value, flattened):
        if isinstance(value, dict):
            for key in value.keys():
                process_value(keys + [key], value[key], flattened)
        elif isinstance(value, list):
            for idx, v in enumerate(value):
                process_value(keys + [str(idx)], v, flattened)
        else:
            flattened['__'.join(keys)] = value

    flattened = {}
    for key in json.keys():
        process_value([key], json[key], flattened)
    return flattened

2

이 시도

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 item in data:
    output.writerow(item.values())

2

이 코드는 주어진 json 파일에서 작동합니다

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 17 20:35:35 2019
author: Ram
"""

import json
import csv

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



# create the csv writer object
pt_data1 = open('pt_data1.csv', 'w')
csvwriter = csv.writer(pt_data1)

count = 0

for pt in data:

      if count == 0:

             header = pt.keys()

             csvwriter.writerow(header)

             count += 1

      csvwriter.writerow(pt.values())

pt_data1.close()

1

내부에 목록이있는 JSON을 지원하도록 수정 된 Alec McGail의 답변

    def flattenjson(self, mp, delim="|"):
            ret = []
            if isinstance(mp, dict):
                    for k in mp.keys():
                            csvs = self.flattenjson(mp[k], delim)
                            for csv in csvs:
                                    ret.append(k + delim + csv)
            elif isinstance(mp, list):
                    for k in mp:
                            csvs = self.flattenjson(k, delim)
                            for csv in csvs:
                                    ret.append(csv)
            else:
                    ret.append(mp)

            return ret

감사!


1
import json,csv
t=''
t=(type('a'))
json_data = []
data = None
write_header = True
item_keys = []
try:
with open('kk.json') as json_file:
    json_data = json_file.read()

    data = json.loads(json_data)
except Exception as e:
    print( e)

with open('bar.csv', 'at') as csv_file:
    writer = csv.writer(csv_file)#, quoting=csv.QUOTE_MINIMAL)
    for item in data:
        item_values = []
        for key in item:
            if write_header:
                item_keys.append(key)
            value = item.get(key, '')
            if (type(value)==t):
                item_values.append(value.encode('utf-8'))
            else:
                item_values.append(value)
        if write_header:
            writer.writerow(item_keys)
            write_header = False
        writer.writerow(item_values)

1

json 형식 파일을 csv 형식 파일로 변환하기 위해 아래 예제를 고려하십시오.

{
 "item_data" : [
      {
        "item": "10023456",
        "class": "100",
        "subclass": "123"
      }
      ]
}

아래 코드는 json 파일 (data3.json)을 csv 파일 (data3.csv)로 변환합니다.

import json
import csv
with open("/Users/Desktop/json/data3.json") as file:
    data = json.load(file)
    file.close()
    print(data)

fname = "/Users/Desktop/json/data3.csv"

with open(fname, "w", newline='') as file:
    csv_file = csv.writer(file)
    csv_file.writerow(['dept',
                       'class',
                       'subclass'])
    for item in data["item_data"]:
         csv_file.writerow([item.get('item_data').get('dept'),
                            item.get('item_data').get('class'),
                            item.get('item_data').get('subclass')])

위에서 언급 한 코드는 로컬로 설치된 pycharm에서 실행되었으며 json 파일을 csv 파일로 성공적으로 변환했습니다. 파일 변환에 도움이되기를 바랍니다.


0

데이터가 사전 형식 인 것처럼 보이므로 실제로 csv.DictWriter ()를 사용하여 실제로 적절한 헤더 정보가있는 행을 출력해야합니다. 이를 통해 변환을 다소 쉽게 처리 할 수 ​​있습니다. 그런 다음 fieldnames 매개 변수는 순서를 올바르게 설정하고 첫 번째 행의 출력은 헤더로서 나중에 csv.DictReader ()에 의해 읽히고 처리 될 수있게합니다.

예를 들어 Mike Repass는

output = csv.writer(sys.stdout)

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

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

그러나 초기 설정을 output = csv.DictWriter (filesetting, fieldnames = data [0] .keys ())로 변경하십시오.

사전의 요소 순서가 정의되어 있지 않으므로 필드 이름 항목을 명시 적으로 작성해야 할 수도 있습니다. 일단 그렇게하면 writerow가 작동합니다. 그런 다음 쓰기는 원래 표시된대로 작동합니다.


0

불행히도 나는 놀라운 @Alec McGail 답변에 작은 공헌을 한 명성을 얻지 못했습니다. Python3을 사용하고 있었고 맵을 @Alexis R 주석 다음의 목록으로 변환해야했습니다.

또한 csv writer가 파일에 추가 CR을 추가하고 있음을 발견했습니다 (csv 파일 내부에 데이터가있는 각 줄마다 빈 줄이 있습니다). 이 스레드에 대한 @Jason R. Coombs의 답변에 따라 솔루션이 매우 쉬웠습니다. 캐리지 리턴을 추가하는 Python의 CSV

csv.writer에 lineterminator = '\ n'매개 변수를 추가하기 만하면됩니다. 그것은 될 것입니다 :csv_w = csv.writer( out_file, lineterminator='\n' )


0

이 코드를 사용하여 JSON 파일을 CSV 파일로 변환 할 수 있습니다 파일을 읽은 후 객체를 팬더 데이터 프레임으로 변환 한 다음 CSV 파일로 저장합니다

import os
import pandas as pd
import json
import numpy as np

data = []
os.chdir('D:\\Your_directory\\folder')
with open('file_name.json', encoding="utf8") as data_file:    
     for line in data_file:
        data.append(json.loads(line))

dataframe = pd.DataFrame(data)        
## Saving the dataframe to a csv file
dataframe.to_csv("filename.csv", encoding='utf-8',index= False)

여기에는 하위 필드 (예 : "필드")가 고려되지 않습니다. 하위 오브젝트는 내용이 개별 열로 분리되는 대신 하나의 열에 있습니다.
Cribber

0

파티에 늦을 수도 있지만 비슷한 문제를 해결했다고 생각합니다. 이처럼 보이는 json 파일이 있습니다.

JSON 파일 구조

이 json 파일에서 키 / 값을 몇 개만 추출하고 싶었습니다. 그래서 나는 동일한 코드를 추출하기 위해 다음 코드를 작성했습니다.

    """json_to_csv.py
    This script reads n numbers of json files present in a folder and then extract certain data from each file and write in a csv file.
    The folder contains the python script i.e. json_to_csv.py, output.csv and another folder descriptions containing all the json files.
"""

import os
import json
import csv


def get_list_of_json_files():
    """Returns the list of filenames of all the Json files present in the folder
    Parameter
    ---------
    directory : str
        'descriptions' in this case
    Returns
    -------
    list_of_files: list
        List of the filenames of all the json files
    """

    list_of_files = os.listdir('descriptions')  # creates list of all the files in the folder

    return list_of_files


def create_list_from_json(jsonfile):
    """Returns a list of the extracted items from json file in the same order we need it.
    Parameter
    _________
    jsonfile : json
        The json file containing the data
    Returns
    -------
    one_sample_list : list
        The list of the extracted items needed for the final csv
    """

    with open(jsonfile) as f:
        data = json.load(f)

    data_list = []  # create an empty list

    # append the items to the list in the same order.
    data_list.append(data['_id'])
    data_list.append(data['_modelType'])
    data_list.append(data['creator']['_id'])
    data_list.append(data['creator']['name'])
    data_list.append(data['dataset']['_accessLevel'])
    data_list.append(data['dataset']['_id'])
    data_list.append(data['dataset']['description'])
    data_list.append(data['dataset']['name'])
    data_list.append(data['meta']['acquisition']['image_type'])
    data_list.append(data['meta']['acquisition']['pixelsX'])
    data_list.append(data['meta']['acquisition']['pixelsY'])
    data_list.append(data['meta']['clinical']['age_approx'])
    data_list.append(data['meta']['clinical']['benign_malignant'])
    data_list.append(data['meta']['clinical']['diagnosis'])
    data_list.append(data['meta']['clinical']['diagnosis_confirm_type'])
    data_list.append(data['meta']['clinical']['melanocytic'])
    data_list.append(data['meta']['clinical']['sex'])
    data_list.append(data['meta']['unstructured']['diagnosis'])
    # In few json files, the race was not there so using KeyError exception to add '' at the place
    try:
        data_list.append(data['meta']['unstructured']['race'])
    except KeyError:
        data_list.append("")  # will add an empty string in case race is not there.
    data_list.append(data['name'])

    return data_list


def write_csv():
    """Creates the desired csv file
    Parameters
    __________
    list_of_files : file
        The list created by get_list_of_json_files() method
    result.csv : csv
        The csv file containing the header only
    Returns
    _______
    result.csv : csv
        The desired csv file
    """

    list_of_files = get_list_of_json_files()
    for file in list_of_files:
        row = create_list_from_json(f'descriptions/{file}')  # create the row to be added to csv for each file (json-file)
        with open('output.csv', 'a') as c:
            writer = csv.writer(c)
            writer.writerow(row)
        c.close()


if __name__ == '__main__':
    write_csv()

이것이 도움이되기를 바랍니다. 이 코드의 작동 방식에 대한 자세한 내용은 여기에서 확인할 수 있습니다


0

이것은 @MikeRepass의 답변을 수정 한 것입니다. 이 버전은 CSV를 파일에 쓰고 Python 2와 Python 3 모두에서 작동합니다.

import csv,json
input_file="data.json"
output_file="data.csv"
with open(input_file) as f:
    content=json.load(f)
try:
    context=open(output_file,'w',newline='') # Python 3
except TypeError:
    context=open(output_file,'wb') # Python 2
with context as file:
    writer=csv.writer(file)
    writer.writerow(content[0].keys()) # header row
    for row in content:
        writer.writerow(row.values())
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.