我正在尝试将非常大的json文件转换为csv。我已经能够将这种类型的小文件转换为10条记录(例如)csv文件。但是,当尝试转换大文件(csv文件中的50000行的数量)时,它不起作用。数据是通过curl命令创建的,其中- o指向要创建的json文件。输出的文件中没有换行符。csv文件将使用csv.DictWriter()编写,并且(其中数据是json文件输入)的格式为
rowcount = len(data['MainKey']) colcount = len(data['MainKey'][0]['Fields'])
然后,我遍历行和列的范围以获取csv词典条目
csvkey = data['MainKey'][recno]['Fields'][colno]['name'] cvsval = data['MainKey'][recno][['Fields'][colno]['Values']['value']
我尝试使用其他问题的答案,但它们不适用于大文件(du -m bigfile.json = 157),而我要处理的文件更大。
du -m bigfile.json = 157
尝试获取每行的大小将显示
myfile = open('file.json','r'). line = readline(): print len(line)
显示这将读取整个文件为完整字符串。因此,一个小文件将显示67744的长度,而大文件将显示163815116。
尝试直接从中读取数据
data=json.load(infile)
给出其他问题针对大文件讨论的错误
尝试使用
def json_parse(self, fileobj, decoder=JSONDecoder(), buffersize=2048): yield results
如另一个答案所示,该文件适用于72 kb的文件(10行22列),但似乎对于中等大小的157 mb文件来说是锁定的或占用无数时间(来自du -m bigfile.json)
请注意,调试打印显示默认输入参数指定的每个块的大小为2048。似乎它试图遍历2048个块中的整个163815116(如上面的len所示)。如果将块大小更改为32768,则简单的数学计算表明,循环需要5,000个周期来处理文件。
更改为524288的块大小后,大约每11个块都会退出循环,但仍应占用大约312个块来处理整个文件
如果我可以将其停在每个行项目的末尾,则可以处理该行并将其发送到基于以下所示形式的csv文件。
小文件上的vi显示它的形式
{"MainKey":[{"Fields":[{"Value": {'value':val}, 'name':'valname'}, {'Value': {'value':val}, 'name':'valname'}}], (other keys)},{'Fields' ... }] (other keys on MainKey level) }
我无法使用ijson,因为我必须为无法导入其他软件的系统进行设置。
为了处理文件,我最后使用了8388608(十六进制0x800000)的块大小。然后,我处理了循环中已读取的行,并保留了已处理行数和已丢弃行数。在每个处理功能中,我将数字添加到总数中,以便可以跟踪已处理的记录总数。
这似乎是它需要走的路。
下次问类似这样的问题时,请强调必须指定较大的块大小,而不是原始答案中所示的2048。
循环去
first = True for data in self.json_parse(inf): records = len(data['MainKey']) columns = len(data['MainKey'][0]['Fields']) if first: # Initialize output as DictWriter ofile, outf, fields = self.init_csv(csvname, data, records, columns) first = False reccount, errcount = self.parse_records(outf, data, fields, records)
在解析例程中
for rec in range(records): currec = data['MainKey'][rec] # If each column count can be different columns = len(currec['Fields']) retval, valrec = self.build_csv_row(currec, columns, fields)
要解析列,请使用
for col in columns: dataname = currec['Fields'][col]['name'] dataval = currec['Fields'][col]['Values']['value']
因此,参考现在可以正常工作,并且处理已正确处理。大块显然允许处理足够快以处理数据,同时又足够小而不会使系统过载。