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

时间:2016-10-30 15:50:31

标签: python json python-2.7 ijson

所以,这是我的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

即使我尝试将其转换为列表,它也不会给我任何回报:

[]

3 个答案:

答案 0 :(得分:2)

您需要指定有效的前缀; ijson前缀是字典中的或列表条目的单词item。您无法选择特定的列表项(因此[2]无效)。

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

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()类将您感兴趣的事件转换为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

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

答案 1 :(得分:0)

鉴于你的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'])

答案 2 :(得分:0)

所以,我将解释我是如何最终解决这个问题的。 第一个答案将起作用。但你必须知道,使用ijson加载每个元素的元素将非常长......到最后,你没有加载的文件。

因此,重要信息是窗口将每个进程的内存限制为2或4 GB ,具体取决于您使用的窗口(32或64)。如果你使用pythonxy,它将是2 GB(它只存在于32)。无论如何,这两种方式都非常低!

我通过在Windows中安装虚拟Linux解决了这个问题,但它确实有效。以下是执行此操作的主要步骤:

  1. 安装Virtual Box
  2. 安装Ubuntu (for exemple)
  3. 在计算机上为科学家安装python,like SciPy
  4. 在2"计算机之间创建共享文件" (你会在google上找到教程)
  5. 在你的ubuntu"计算机上执行你的代码":它可以工作;)
  6. 注意:不要忘记为虚拟计算机留出足够的RAM和内存。

    这对我有用。我不再有这个"记忆错误"问题