如何使用Python ijson读取大型JSON文件?
我正试图解析一个大的json文件(数百gig)以从其密钥中提取信息。为了简单起见,考虑下面的例子:如何使用Python ijson读取大型JSON文件?,python,json,python-2.7,ijson,Python,Json,Python 2.7,Ijson,我正试图解析一个大的json文件(数百gig)以从其密钥中提取信息。为了简单起见,考虑下面的例子: import random, string # To create a random key def random_string(length): return "".join(random.choice(string.lowercase) for i in range(length)) # Create the dicitonary dummy = {random_str
import random, string
# To create a random key
def random_string(length):
return "".join(random.choice(string.lowercase) for i in range(length))
# Create the dicitonary
dummy = {random_string(10): random.sample(range(1, 1000), 10) for times in range(15)}
# Dump the dictionary into a json file
with open("dummy.json", "w") as fp:
json.dump(dummy, fp)
然后,我在python 2.7中使用ijson解析文件:
file_name = "dummy.json"
with open(file_name, "r") as fp:
for key in dummy.keys():
print "key: ", key
parser = ijson.items(fp, str(key) + ".item")
for number in parser:
print number,
我希望检索列表中与dic键对应的所有数字。然而,我得到了
不完整JSONERROR:不完整的JSON数据
我知道这篇文章:,但在我的例子中,我有一个格式良好的json文件,具有一个相对简单的模式。关于如何解析它有什么想法吗?多谢各位 ijson有一个迭代器接口来处理大型JSON文件,允许延迟读取文件。您可以将文件分成小块进行处理,并将结果保存到其他地方 您可以调用方法
ijson.parse()
,该方法生成三个值前缀、事件、值
一些JSON:
{
"europe": [
{"name": "Paris", "type": "city"},
{"name": "Rhein", "type": "river"}
]
}
import ijson
data = ijson.parse(open(FILE_PATH, 'r'))
for prefix, event, value in data:
if event == 'string':
print(value)
Paris
city
Rhein
river
代码:
{
"europe": [
{"name": "Paris", "type": "city"},
{"name": "Rhein", "type": "river"}
]
}
import ijson
data = ijson.parse(open(FILE_PATH, 'r'))
for prefix, event, value in data:
if event == 'string':
print(value)
Paris
city
Rhein
river
输出:
{
"europe": [
{"name": "Paris", "type": "city"},
{"name": "Rhein", "type": "river"}
]
}
import ijson
data = ijson.parse(open(FILE_PATH, 'r'))
for prefix, event, value in data:
if event == 'string':
print(value)
Paris
city
Rhein
river
参考:示例json
内容文件如下:它有两个人的记录。它可能有200万条记录
[
{
"Name" : "Joy",
"Address" : "123 Main St",
"Schools" : [
"University of Chicago",
"Purdue University"
],
"Hobbies" : [
{
"Instrument" : "Guitar",
"Level" : "Expert"
},
{
"percussion" : "Drum",
"Level" : "Professional"
}
],
"Status" : "Student",
"id" : 111,
"AltID" : "J111"
},
{
"Name" : "Mary",
"Address" : "452 Jubal St",
"Schools" : [
"University of Pensylvania",
"Washington University"
],
"Hobbies" : [
{
"Instrument" : "Violin",
"Level" : "Expert"
},
{
"percussion" : "Piano",
"Level" : "Professional"
}
],
"Status" : "Employed",
"id" : 112,
"AltID" : "M112"
}
}
]
我创建了一个生成器,将每个人的记录作为json
对象返回。代码如下所示。这不是发电机代码。换几条线就成了发电机
导入json
curly_idx=[]
jstr=“”
first\u curly\u found=错误
将open(“C:\\Users\\Rajeshs\\PycharmProjects\\Project1\\data\\test.json,'r')作为fp:
#逐行读取文件
line=fp.readline()
lnum=0
while line:
对于直列:
如果a=='{':
curly_idx.append(lnum)
first_curly_found=真
elif a=='}':
curly_idx.pop()
#当找到每个左卷发对应的右卷发时,
#这意味着读取了一个完整的数据元素
如果len(curly_idx)==0,并且第一次发现:
jstr=f'{jstr}{line}'
jstr=jstr.rstrip()
jstr=jstr.rstrip(',')
jstr[:-1]
印刷品(“--------------------”)
如果len(jstr)>10:
打印(“制作json”)
j=json.loads(jstr)
打印(jstr)
jstr=“”
line=fp.readline()
lnum+=1
持续
如果发现第一个卷发:
jstr=f'{jstr}{line}'
line=fp.readline()
lnum+=1
如果lnum>100:
打破
您正在使用同一文件对象启动多个解析迭代,而不重置它。对ijson的第一个调用将起作用,但会将file对象移动到文件的末尾;然后,第二次将同一个.object传递给ijson时,它会抱怨,因为不再需要从文件中读取任何内容
尝试在每次调用ijson时打开文件;或者,您可以在调用ijson后查找文件的开头,以便file对象可以再次读取您的文件数据。上面的示例生成一个字典,解析器为其生成我描述的错误。这是不一样的。您不能将ijson.items用于大文件,它不会读取整个文件,并且会出现错误。对于大文件,您需要小心使用由ijson.items()
或ijson.parse()
)返回的生成器,例如,您应该避免通过集(您的\u生成器)
或列表获取值(您的\u生成器)