use*_*396 31 python parsing json pandas
我是Json文件的新手.如果我有一个带有多个json对象的json文件,如下所示:
{"ID":"12345","Timestamp":"20140101", "Usefulness":"Yes",
"Code":[{"event1":"A","result":"1"},…]}
{"ID":"1A35B","Timestamp":"20140102", "Usefulness":"No",
"Code":[{"event1":"B","result":"1"},…]}
{"ID":"AA356","Timestamp":"20140103", "Usefulness":"No",
"Code":[{"event1":"B","result":"0"},…]}
…
Run Code Online (Sandbox Code Playgroud)
我想将所有"时间戳"和"有用性"提取到数据框中:
Timestamp Usefulness
0 20140101 Yes
1 20140102 No
2 20140103 No
…
Run Code Online (Sandbox Code Playgroud)
有谁知道处理这些问题的一般方法?谢谢!
Dun*_*nes 67
您可以使用json.JSONDecoder.raw_decode
任意解码大量"堆叠"JSON字符串(只要它们可以适合内存).raw_decode
一旦它有一个有效的对象就停止,并返回不在解析对象中的最后一个位置.它没有记录,但您可以将此位置传回,raw_decode
并从该位置再次开始解析.不幸的是,Python json
模块不接受具有前缀空格的字符串.所以我们需要搜索以找到文档的第一个非空白部分.
from json import JSONDecoder, JSONDecodeError
import re
NOT_WHITESPACE = re.compile(r'[^\s]')
def decode_stacked(document, pos=0, decoder=JSONDecoder()):
while True:
match = NOT_WHITESPACE.search(document, pos)
if not match:
return
pos = match.start()
try:
obj, pos = decoder.raw_decode(document, pos)
except JSONDecodeError:
# do something sensible if there's some error
raise
yield obj
s = """
{"a": 1}
[
1
,
2
]
"""
for obj in decode_stacked(s):
print(obj)
Run Code Online (Sandbox Code Playgroud)
打印:
{'a': 1}
[1, 2]
Run Code Online (Sandbox Code Playgroud)
dan*_*nca 23
使用json数组,格式为:
[
{"ID":"12345","Timestamp":"20140101", "Usefulness":"Yes",
"Code":[{"event1":"A","result":"1"},…]},
{"ID":"1A35B","Timestamp":"20140102", "Usefulness":"No",
"Code":[{"event1":"B","result":"1"},…]},
{"ID":"AA356","Timestamp":"20140103", "Usefulness":"No",
"Code":[{"event1":"B","result":"0"},…]},
...
]
Run Code Online (Sandbox Code Playgroud)
然后将其导入您的python代码
import json
with open('file.json') as json_file:
data = json.load(json_file)
Run Code Online (Sandbox Code Playgroud)
现在,数据的内容是一个数组,其中的字典代表每个元素.
您可以轻松访问它,即:
data[0]["ID"]
Run Code Online (Sandbox Code Playgroud)
因此,正如在几个注释中提到的那样,将数据包含在数组中比较简单,但是随着数据集大小的增加,该解决方案在效率方面无法很好地扩展。当您要访问数组中的随机对象时,实际上仅应使用迭代器,否则,生成器是您的理想之选。下面,我原型化了一个读取器函数,该函数分别读取每个json对象并返回一个生成器。
基本思想是向读者发出信号,让他们分割回车符“ \ n”(对于Windows,则为“ \ r \ n”)。Python可以使用文件 .readline()函数来完成此操作。
import json
def json_readr(file):
for line in open(file, mode="r"):
yield json.loads(line)
Run Code Online (Sandbox Code Playgroud)
但是,只有在按原样写入文件时,此方法才真正起作用-每个对象都用换行符分隔。在下面,我写了一个编写器的示例,该示例将json对象数组分开并将每个对象保存在新行中。
def json_writr(file, json_objects):
f = open(file, mode="w")
for jsonobj in json_objects:
jsonstr = json.dumps(jsonobj)
f.write(jsonstr+"\n")
f.flush()
f.close()
Run Code Online (Sandbox Code Playgroud)
您还可以对文件 .writelines()和列表理解进行相同的操作
...
jsobjs = [json.dumps(j)+"\n" for j in json_objects]
f.writelines(jsobjs)
...
Run Code Online (Sandbox Code Playgroud)
如果您想追加数据而不是写入新文件,只需将'mode =“ w”'更改为'mode =“ a”'。
最后,我发现这不仅在尝试在文本编辑器中打开json文件时提高了可读性,而且在更有效地使用内存方面也有很大帮助。
关于这一点,如果您在某个时候改变了主意,并且希望将列表从阅读器中删除,Python允许您将生成器函数放在列表中,并自动填充列表。换句话说,只要写
lst = list(json_readr(file))
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助。抱歉,如果有点冗长。
根据@dunes的答案添加了流媒体支持:
import re
from json import JSONDecoder, JSONDecodeError
NOT_WHITESPACE = re.compile(r"[^\s]")
def stream_json(file_obj, buf_size=1024, decoder=JSONDecoder()):
buf = ""
ex = None
while True:
block = file_obj.read(buf_size)
if not block:
break
buf += block
pos = 0
while True:
match = NOT_WHITESPACE.search(buf, pos)
if not match:
break
pos = match.start()
try:
obj, pos = decoder.raw_decode(buf, pos)
except JSONDecodeError as e:
ex = e
break
else:
ex = None
yield obj
buf = buf[pos:]
if ex is not None:
raise ex
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
67352 次 |
最近记录: |