所以我有一个程序读取json,展平它并转储csv:
import json
import unicodecsv as csv
import sys
import glob
import os
from flatten_json import flatten_json
def createcolumnheadings(cols):
#create column headings
columns = cols.keys()
columns = list( set( columns ) )
return columns
doOnce=True
path=os.chdir(sys.argv[1])
for f in glob.glob("smallR.txt"):
fName=os.path.splitext(f)[0]
out_file= open( 'csv/' + fName+'.csv', 'wb' )
csv_w = csv.writer( out_file, delimiter="\t", encoding='utf-8' )
with open(f, 'r') as handle:
for line in handle:
data = json.loads(line)
flatdata =flatten_json(data)
if doOnce:
columns=createcolumnheadings(flatdata)
columns.insert(0,'racism')
csv_w.writerow( columns)
doOnce=False
flatdata['racism']= 0
csv_w.writerow(flatdata.get(x, u'') for x in columns)
这有效,有一个问题。 我的程序只是从smallR.txt的第一行获取列标题(加上它添加了一个'Racism'列)。
后面的一些数据(smallR.txt here)有不同的列。这导致输出不太正确,请参阅small.csv here。
是否有一种简单的方法可以调整我的程序来处理后续行中的新列标题?
答案 0 :(得分:1)
在这种情况下,您需要先扫描整个文件,以获取所有可能的列:
with open(f, 'r') as handle:
data = [json.loads(line) for line in handle]
columns = ['racism'] + list({k for entry in data for k in entry.keys()})
csv_w.writerow(columns)
for entry in entries:
csv_w.writerow(entry.get(c, '') for c in columns)
此加载内存中的所有数据。如果你不接受这个,你可能会读两次文件:一个用于获取列,另一个用于读写:
with open(f, 'r') as handle:
columns = ['racism'] + list({k for line in handle for k in json.load(line).keys()})
csv_w.write(columns)
with open(f, 'r') as handle:
for line in handle:
entry = json.loads(line)
csv_w.write(entry.get(c, '') for c in columns)
缺少 flatten_json 函数定义,所以我只能猜测它的作用。