从大型 json 文件中加载 python 的元素

Load an element with python from large json file

所以,这是我的 json 文件。我想从中加载数据列表,一个一个地加载它。 然后,例如绘制它...

这是一个例子,因为我正在处理大数据集,我无法加载所有文件(这会造成内存错误)。

{
  "earth": {
    "europe": [
      {"name": "Paris", "type": "city"},
      {"name": "Thames", "type": "river"}, 
      {"par": 2, "data": [1,7,4,7,5,7,7,6]}, 
      {"par": 2, "data": [1,0,4,1,5,1,1,1]}, 
      {"par": 2, "data": [1,0,0,0,5,0,0,0]}
        ],
    "america": [
      {"name": "Texas", "type": "state"}
    ]
  }
}

这是我试过的:

import ijson
filename = "testfile.json"

f = open(filename)
mylist = ijson.items(f, 'earth.europe[2].data.item')
print mylist

它 returns 我什么都没有,即使我试图将它转换成列表:

[]

鉴于你的结构 json 我会这样做:

import json

filename = "test.json"

with open(filename) as data_file:
    data = json.load(data_file)
print data['earth']['europe'][2]['data']
print type(data['earth']['europe'][2]['data'])

您需要指定一个有效的前缀; ijson 前缀是字典中的 或列表条目的单词 item。您不能 select 特定的列表项(因此 [2] 不起作用)。

如果您想要 europe 列表中的所有 data 键字典,那么前缀是:

earth.europe.item.data
# ^ ------------------- outermost key must be 'earth'
#       ^ ------------- next key must be 'europe'
#              ^ ------ any value in the array
#                   ^   the value for the 'data' key

这会生成每个这样的列表:

>>> l = ijson.items(f, 'earth.europe.item.data')
>>> for data in l:
...     print data
...
[1, 7, 4, 7, 5, 7, 7, 6]
[1, 0, 4, 1, 5, 1, 1, 1]
[1, 0, 0, 0, 5, 0, 0, 0]

你不能在里面放通配符,所以你不能得到 earth.*.item.data 例如。

如果您需要进行更复杂的前缀匹配,则必须使用 ijson.parse() 函数并处理它产生的事件。您可以重复使用 ijson.ObjectBuilder() class 将您感兴趣的事件变成 Python 对象:

parser = ijson.parse(f)
for prefix, event, value in parser:
    if event != 'start_array':
        continue
    if prefix.startswith('earth.') and prefix.endswith('.item.data'):
        continent = prefix.split('.', 2)[1]
        builder = ijson.ObjectBuilder()
        builder.event(event, value)
        for nprefix, event, value in parser:
            if (nprefix, event) == (prefix, 'end_array'):
                break
            builder.event(event, value)
        data = builder.value
        print continent, data

这将使用 'earth' 键打印 'data' 键下的列表中的每个数组(因此位于以 '.item.data' 结尾的前缀下)。它还提取大陆密钥。

所以,我将解释我是如何最终解决这个问题的。 第一个答案有效。但是你要知道用ijson一个一个的加载元素会很长...最后你没有加载的文件

因此,重要的信息是 windows 将每个进程的内存限制为 2 或 4 GB,具体取决于 windows 您使用的 (32或 64).如果您使用 pythonxy,那将是 2 GB(它只存在于 32)。不管怎样,从这两个方面来说,都是非常非常低的!

我通过在我的 windows 中安装虚拟 Linux 解决了这个问题,并且它有效。以下是这样做的主要步骤:

  1. 安装Virtual Box
  2. 安装Ubuntu(for exemple)
  3. 在您的计算机上安装 python for scientist,like SciPy
  4. 在 2 "computers" 之间创建共享文件(您将在 google 上找到教程)
  5. 在你的 ubuntu "computer" 上执行你的代码:它应该可以工作 ;)

注意:不要忘记为您的虚拟计算机提供足够的 RAM 和内存。

这对我有用。我再也没有这个 "memory error" 问题了。