我正在尝试将一个非常大的 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),而且我要处理的文件更大.
尝试获取每一行显示的大小
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
如another answer所示,适用于 72 kb 的文件(10 行,22 列),但对于 157 mb 的中间大小的文件(来自 du -m bigfile.json)似乎要么锁定要么花费无穷无尽的时间
请注意,调试打印显示每个 block 的大小为 2048,由默认输入参数指定。看起来它正试图以 2048 个 block 遍历整个 163815116(从上面的 len 显示)。如果我将 block 大小更改为 32768,简单的数学表明处理该文件需要 5,000 个循环周期。
将 block 大小更改为 524288 大约每 11 个 block 退出循环,但仍需要大约 312 个 block 来处理整个文件
如果我能让它在每个行项目的末尾停止,我就能够处理该行并根据下面显示的表格将其发送到 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 十六进制)的 block 大小来处理文件。然后我处理作为循环的一部分读入的行,记录处理的行数和丢弃的行数。在每个流程功能中,我将数字添加到总数中,以便我可以跟踪处理的总记录数。
这似乎是它需要走的路。
下次问这样的问题时,请强调必须指定大块大小,而不是原始答案中显示的 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']
因此,引用现在可以工作,处理也得到了正确处理。大块显然允许处理足够快以处理数据,同时足够小不会使系统过载。
