JSON を CSV に変換するにはどうすればよいですか?
質問
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:
f.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:
csv_file.writerow(item)
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
図書館, これは 2 つのコマンドを使用するのと同じくらい簡単です。
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オブジェクトの入力アレイの各辞書には、この機能を適用した後:
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「オブジェクト」として長い間、JSおおよそPythonのリストのような「アレイ」、とあなたはネストでき、それらをとほぼ(文字列キー付き)Pythonの辞書のようなものです最後の「リーフ」の要素は、数値または文字列です。
CSVは、本質的に2次元テーブルを表すことができ、 - 必要に応じてdictsのリストとしてテーブルを解釈することができ、「ヘッダ」、すなわち、「列名」の最初の行ではなく、通常の解釈の、リストのリスト(再び、「リーフ」の要素は、数値や文字列ことができます)。
ですから、一般的なケースでは、あなたはCSVに任意のJSON構造を変換することはできません。 (;すべてが正確に同じキーを持つオブジェクトの配列がない、さらに入れ子にして配列の配列)することができますいくつかの特別なケースでは。特別なその場合、もしあれば、あなたの問題に適用されますか?ソリューションの詳細については、あなたが持っていないその特殊なケースに依存します。あなたも1が適用される言及していないという驚くべき事実を考えると、私はあなたが制約と考えられていない可能性が疑われるが、実際に使用可能な場合どちらが適用され、あなたの問題を解決することは不可能です。しかし、明確にしてください!
一般的な解決策ます。
コマンドラインの最初の引数として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オブジェクトのすべてが同じフィールドを持っていることを前提としています。
ここであなたを助けるかもしれ参照ではあります。
私はダンの提案したソリューションするとのトラブルを抱えていたが、これは私のために働いてます:
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 } }
]
2Dデータ構造であるCSVを詩。ただし、CSVファイルへの多次元構造をオンにする良い方法は、主キーと一緒に結ぶ複数のCSVを持つことです。
あなたの例では、最初のCSV出力は、あなたの列として列「PK」、「モデル」、「フィールド」を持っています。 「PK」の値、および「モデル」を取得するのは簡単ですが、「フィールド」の欄には辞書が含まれているため、それは自身のcsvファイルである必要があり、「コードネームは」あなたが入力として使用することができ、主キー、のように見えるので、 「フィールド」のための最初のCSVを完了します。第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")
私はこの質問が尋ねてきたので、それは長い時間となっている知っているが、私は皆の答えに追加して、私は非常に簡潔な方法で解決策を説明すると思うのブログ記事を共有するかもしれないと思っています。
ここでリンクですの
を記述するためのファイルを開きます。
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()
このは比較的うまく機能。 これは、csvファイルにそれを書くためにJSONを平坦化します。 ネストされた要素が管理されています)。
これは、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)
楽しむます。
これを解決するために私の簡単な方法:
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
私は、これはあなたを助けることを願っています。
SEEYA!
それはそれを行うには非常にスマートな方法ではありませんが、私は同じ問題があったし、これは私のために働いてます:
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()
タグ内のリストとJSONをサポートするために、アレック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
ありがとうございます。
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)
これを試してみてください。
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())
このコードは、任意の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()
アレックの答えには素晴らしいですが、それは、ネストの複数のレベルがある場合には動作しません。ここでは、ネストの複数のレベルをサポートして修正されたバージョンです。ネストされたオブジェクトが既に独自のキーを指定している場合、それはまた、ヘッダ名ビットよりよいを行う(例えばFirebaseアナリティクス/ 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)
データ辞書形式であるように見えるので、それはあなたが実際csv.DictWriter()を使用するように思わに実際に出力適切なヘッダ情報をライン。これは、変換がいくらか容易に処理できるようにする必要があります。ヘッダとして最初の行の出力は、それが読み出され、csv.DictReader()によって後に処理されることを可能にするであろうしながらフィールド名パラメータは、次に適切順序を設定します。
例えば、マイクRepassが使用
output = csv.writer(sys.stdout)
output.writerow(data[0].keys()) # header row
for row in data:
output.writerow(row.values())
しかしただの初期設定を変更します 出力= csv.DictWriter(filesetting、フィールド名=データ[0] .keys())
辞書内の要素の順序が定義されていないので、明示的にフィールド名のエントリを作成する必要がある場合がありますので注意してください。あなたがそれを行うならば、のwriterowが動作します。書き込みはその後、もともと示すように動作します。
残念ながら、私は素晴らしい@Alec McGailの答えに小さな貢献をするために評判をenouthgしていません。 私はのpython3を使用していたと私は@Alexis Rコメント次のリストにマップを変換する必要がありました。
Additionaly Iは、CSVライタ(I CSVファイル内のデータとライン毎に空白行を持っている)ファイルに余分なCRを追加した見出しました。ソリューションは、このスレッドに@Jason R.クームス答え、次の非常に簡単でした。
の余分なキャリッジリターンを追加するPythonでCSVをhref="https://stackoverflow.com/questions/3191528/csv-in-python-adding-an-extra-carriage-return#17725590"> P>
あなたは、単にcsv.writerにlineterminator =「\ n」のパラメータを追加する必要があります。それは次のようになります。csv_w = csv.writer( out_file, lineterminator='\n' )
驚くべきことに、私はこれまでのところ、正しくここに掲載の答えのどれもがすべての可能なシナリオ(例えば、ネストされた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
あなたはCSVファイルにJSONファイルを変換するには、このコードを使用することができます ファイルを読んだ後、私はパンダのデータフレームにオブジェクトを変換しています後、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)
私はパーティーに遅れるかもしれないが、私が思うに、私は同様の問題を扱ってきました。私はこのように見えた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()
私はこれが役立つことを願っています。どのようにこのコードの動作の詳細についてはこちらのページを確認することができますする