Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Python ijson读取大型JSON文件?_Python_Json_Python 2.7_Ijson - Fatal编程技术网

如何使用Python ijson读取大型JSON文件?

如何使用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

我正试图解析一个大的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_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生成器)