我对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"},…]}
…
我想提取所有"时间戳"和"实用性"进入数据框:
Timestamp Usefulness
0 20140101 Yes
1 20140102 No
2 20140103 No
…
有谁知道处理此类问题的一般方法?谢谢!
答案 0 :(得分:43)
您可以使用json.JSONDecoder.raw_decode
来解码任意大字符串"堆叠" JSON(只要它们可以适合内存)。 raw_decode
一旦有了有效对象就停止,并返回最后一个位置,其中isn是解析对象的一部分。它没有记录,但您可以将此位置传回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)
打印:
{'a': 1}
[1, 2]
答案 1 :(得分:21)
使用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"},…]},
...
]
然后将其导入您的python代码
import json
with open('file.json') as json_file:
data = json.load(json_file)
现在数据的内容是一个数组,其中的字典代表每个元素。
您可以轻松访问它,即:
data[0]["ID"]
答案 2 :(得分:5)
因此,正如在几个包含数组中的数据的注释中所提到的那样简单,但随着数据集大小的增加,解决方案在效率方面不能很好地扩展。当你想要访问数组中的随机对象时,你真的应该只使用迭代器,否则,生成器是可行的方法。下面我原型了一个reader函数,它单独读取每个json对象并返回一个生成器。
基本思想是通知读者分割托架字符“\ n”(或Windows的“\ r \ n”)。 Python可以使用文件 .readline()函数执行此操作。
import json
def json_readr(file):
for line in open(file, mode="r"):
yield json.loads(line)
但是,此方法仅在您按原样编写文件时才真正起作用 - 每个对象用新行字符分隔。下面我写了一个编写器的例子,它分隔了一个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()
您也可以使用文件 .writelines()和列表理解进行相同的操作
...
jsobjs = [json.dumps(j)+"\n" for j in json_objects]
f.writelines(jsobjs)
...
如果您想要附加数据而不是写新文件,只需将'mode =“w”'更改为'mode =“a”'。
最后,我发现当我尝试在文本编辑器中打开json文件时,以及在更有效地使用内存方面,这不仅有助于提高可读性。
在那个注意事项中,如果你在某个时候改变了想法,并且想要一个读者列表,那么Python允许你将一个生成器函数放在一个列表中并自动填充列表。换句话说,只需写
lst = list(json_readr(file))
希望这会有所帮助。对不起,如果它有点冗长。
答案 3 :(得分:2)
根据@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
答案 4 :(得分:-2)
在解析对象时,您正在处理字典。您可以通过搜索键来提取所需的值。例如。 value = jsonDictionary['Usefulness']
。
您可以使用for循环遍历json
个对象。 e.g:
for obj in bunchOfObjs:
value = obj['Usefulness']
#now do something with your value, e.g insert into panda....