JSONをCSVに変換するにはどうすればよいですか?


184

CSVファイルに変換するJSONファイルがあります。Pythonでこれを行うにはどうすればよいですか?

私は試した:

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)では、アイテムは文字列または数値の単純なリストである必要があります。{"pk":22、 "model": "auth.permission"}が[22、auth.permission]になるように、各jsonオブジェクトをフラットリストに変換してみてください。
Suppressingfire、

1
これへの簡単なアプローチはjq、ここで説明するようにを使用することです。stackoverflow.com
questions

サードパーティの代替手段:json-csv.com(1回限りの変換の場合)またはjson-csv.com/api。Pythonで自動化します。これは、より複雑なJSON構造のためのシンプルなソリューションです。
スタックマン、

回答:


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
これはうまくいきましたが、前に申し訳ありませんが、ハードコーディングされていないものを取得できます。f.writerow(a)を使用してIDを変更できます。aは、感謝の前に宣言する変数です
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'])
Aditya Hariharan

8
python3の場合、csvファイルを開く行をf = csv.writer(open("test.csv", "w", newline=''))
PiotrK

118

ではpandas 、ライブラリこれは2つのコマンドを使用するのと同じくらい簡単です!

pandas.read_json()

JSON文字列をパンダオブジェクト(シリーズまたはデータフレーム)に変換します。次に、結果が次のように格納されていると仮定します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))"。なぜ反復可能では不十分なのか理解できません。私のデータはUTF8を使用しているため、出力ファイルを開くときにもエンコーディングを指定する必要がありました。それは間違いなく助けました、ありがとう!!
Alexis R

これは素晴らしいです、アレックに感謝します!ネストの複数のレベルで動作するように変更しました:stackoverflow.com/a/57228641/473201
phreakhead

35

JSONはさまざまなデータ構造を表すことができます-JS「オブジェクト」はおおよそPython dict(文字列キー付き)に似ており、JS「配列」はおおざっぱにPythonリストに似ており、最後の「 「葉」要素は数値または文字列です。

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がギザギザになっていなかったため、既存のスクリプト内でこれを実行していたので、JSONがギザギザにならなかったため、これは私が必要とするソリューションの大部分でした。
MichaelF 14

1
このコードは、値がヘッダー行のキーと同じ順序で出力されることも想定しています。それは運でうまくいったかもしれませんが、保証されるものではありません。
RyanHennig 2015

エンコーディングエラーを取得しています。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.writerowf.writerowもちろんありません。あなたがそこにタイプミスをしたと思います!)はdictではなくシーケンスを望んでいます-そして、あなたの例では、各アイテムはdictです。これは、私の答えで特定したように、JSONファイルに配列の配列がある他の特殊なケースで機能します。オブジェクトの配列では機能しません。これは、解決しようとしているように見える特殊なケースです(これには、csv.DictWriter-が必要です。もちろん、インスタンス化するには、フィールド名を抽出し、順序を決定する必要があります。 !-)。
Alex Martelli、

@DanLoewenherzこれは、最近のPythonバージョンでは機能しません。TypeError:リストすることができるのは( "dict_values"ではなく)リストを連結することだけです
Apolo Radomer '24 / 07/19

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オブジェクトに同じフィールドがあることを前提としています。

こちらが参考になる参考資料です。


このリンクで質問に答えることができますが、回答の重要な部分をここに含め、参照用のリンクを提供することをお勧めします。リンクされたページが変更されると、リンクのみの回答が無効になる可能性があります。- 口コミより
マチュー

3
@purplepsycho私はこの回答を反対投票で見つけました。リンクだけが良い答えではないことを知らなかったかもしれない新しいユーザーは、それを修正しました。私は賛成した。新しいユーザーに引き続きコミュニティへの参加を促すには、おそらくあなたもできるでしょうか?
Mawgはモニカを2017

6

ダンが提案した解決策に問題がありましたが、これでうまくいきました。

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(最後の最新の呼び出し)でプログラムを実行しようとしてエラーが発生しました:ファイル "json2csv.py"、11行目<module> f.writerow([item ['pk ']、item [' model ']] + item [' fields ']。values())TypeError:リストする( "dict_values"ではない)リストのみを連結できます
Mian Asbat Ahmad

ちょうど今Python 2.7.9でもう一度試してみましたが、私にとってはうまくいきました。
アマンダ

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を完成させます。2番目のcsvには、「フィールド」列の辞書が含まれ、2つのcsvを結合するために使用できる主キーとしてコードネームが含まれています。

ネストされた辞書を2つのcsvに変換する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

アレックの答えは素晴らしいですが、ネストのレベルが複数ある場合は機能しません。以下は、複数レベルのネストをサポートする修正バージョンです。また、ネストされたオブジェクトがすでに独自のキーを指定している場合(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ファイルに書き込みます。ネストされた要素は管理されます:)

それはPython 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。これにより、リストオブジェクトが適切に生成されます。3番目に、ネストされた要素が失われました。
ZygD

2

これを解決する私の簡単な方法:

次のような新しいPythonファイルを作成します。json_to_csv.py

このコードを追加します。

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
このサンプルは魅力のように機能します!共有してくれてありがとうこのPythonスクリプトを使用してjsonファイルをCSVに変換できました
Mostafa

2

驚いたことに、ここに投稿された回答のいずれも、これまでに考えられるすべてのシナリオ(たとえば、ネストされた辞書、ネストされたリスト、値なしなど)を正しく処理していないことがわかりました。

このソリューションは、すべてのシナリオで機能するはずです。

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()がそれを読み取って処理できるようになります。

たとえば、マイクリパスは

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ライターがファイルに追加のCRを追加していることを発見しました(csvファイル内のデータを含む各行に空の行があります)。この解決策は、@ Jason R. Coombsがこのスレッドに答えた後、非常に簡単でした。PythonでCSVを使用すると、改行が追加されます

単にlineterminator = '\ n'パラメータをcsv.writerに追加する必要があります。そうなる:csv_w = csv.writer( out_file, lineterminator='\n' )


0

このコードを使用して、jsonファイルをcsvファイルに変換できます。ファイルを読み取った後、オブジェクトをpandasデータフレームに変換し、これを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)

これはサブフィールド(例の「フィールド」など)を考慮に入れていません。サブオブジェクトは、内容が個別の列に分けられているのではなく、1つの列にあります。
クリバー

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.