Cat*_*Cat 21 python parsing json large-files
我正在尝试加载一个填充了JSON字符串的大文件(大小为2GB),由换行符分隔.例如:
{
"key11": value11,
"key12": value12,
}
{
"key21": value21,
"key22": value22,
}
…
Run Code Online (Sandbox Code Playgroud)
我现在导入它的方式是:
content = open(file_path, "r").read()
j_content = json.loads("[" + content.replace("}\n{", "},\n{") + "]")
Run Code Online (Sandbox Code Playgroud)
这似乎是一个黑客(在每个JSON字符串之间添加逗号以及开始和结束方括号以使其成为正确的列表).
有没有更好的方法来指定JSON分隔符(换行符\n而不是逗号,)?
而且,Python似乎无法为从2GB数据构建的对象正确分配内存,有没有办法构建每个JSON对象,因为我正在逐行读取文件?谢谢!
njz*_*zk2 28
只需读取每一行并在此时构造一个json对象:
with open(file_path) as f:
for line in f:
j_content = json.loads(line)
Run Code Online (Sandbox Code Playgroud)
这样,您加载正确的完整json对象(假设json对象\n中某处或json对象中没有json值),并且在需要时创建每个对象时避免内存问题.
还有这个答案:
contents = open(file_path, "r").read()
data = [json.loads(str(item)) for item in contents.strip().split('\n')]
Run Code Online (Sandbox Code Playgroud)
这适用于您提供的特定文件格式.如果您的格式发生变化,那么您需要更改分析行的方式.
{
"key11": 11,
"key12": 12
}
{
"key21": 21,
"key22": 22
}
Run Code Online (Sandbox Code Playgroud)
只需逐行阅读,并随时构建JSON块:
with open(args.infile, 'r') as infile:
# Variable for building our JSON block
json_block = []
for line in infile:
# Add the line to our JSON block
json_block.append(line)
# Check whether we closed our JSON block
if line.startswith('}'):
# Do something with the JSON dictionary
json_dict = json.loads(''.join(json_block))
print(json_dict)
# Start a new block
json_block = []
Run Code Online (Sandbox Code Playgroud)
如果您有兴趣解析一个非常大的JSON文件而不将所有内容都保存到内存中,那么您应该查看json.load API中使用object_hook或object_pairs_hook回调方法.
这扩展了科恩的答案:
content_object = s3_resource.Object(BucketName, KeyFileName)
file_buffer = io.StringIO()
file_buffer = content_object.get()['Body'].read().decode('utf-8')
json_lines = []
for line in file_buffer.splitlines():
j_content = json.loads(line)
json_lines.append(j_content)
df_readback = pd.DataFrame(json_lines)
Run Code Online (Sandbox Code Playgroud)
这假设整个文件适合内存。如果它太大,则必须对其进行修改以分块读取或使用Dask。