1

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

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

[]
4

3 回答 3

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'键。它还提取大陆键。

于 2016-11-02T18:02:05.510 回答
0

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

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

我通过在我的 Windows 中安装一个虚拟 Linux 解决了这个问题,它可以工作。以下是这样做的主要步骤:

  1. 安装虚拟盒子
  2. 安装 Ubuntu (例如)
  3. 在您的计算机上为科学家安装 python,例如 SciPy
  4. 在两台“计算机”之间创建一个共享文件(您可以在 google 上找到教程)
  5. 在您的 ubuntu“计算机”上执行您的代码:它应该可以工作;)

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

这对我有用。我不再有这个“内存错误”问题。

于 2016-11-08T14:53:29.087 回答
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'])
于 2016-10-30T18:51:23.890 回答