【问题标题】:Load an element with python from large json file从大型 json 文件中使用 python 加载元素
【发布时间】:2016-10-30 15:50:30
【问题描述】:

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

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

[]

【问题讨论】:

  • 我没有放我使用的代码,因为我认为这不是一个好方法... import ijson as ijson filename = "myfile.json" with open(myfile,' r') as f: 瞧=ijson.items(f,'earth.data.item') 打印瞧
  • 我开发了,你有什么想法
  • 感谢更新,我已经重新打开了。
  • 我想我会删除...没有人回应...

标签: python json python-2.7 ijson


【解决方案1】:

您需要指定一个有效的前缀; ijson 前缀要么是字典中的键,要么是用于列表条目的单词item。您无法选择特定的列表项(因此 [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() 类将您感兴趣的事件转换为 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' 结尾的前缀下)。它还提取大陆键。

【讨论】:

  • 非常感谢!即使我必须为第二部分集中精力,这也是我在互联网上找到的最好的解释:))
  • 我想你已经回答了这个问题,但是有没有办法一一加载这些数据?因为,如果我想处理它们,我必须(例如)将它们存储在一个列表中。同样的问题再次发生:“内存错误”。有什么想法吗?
  • @JeanneDiderot:是的,我现在使用print,你可以只处理一个列表,然后丢弃它。或者您可以将整个内容包装到一个函数中,使用yield continent, data 让它在您迭代时一个一个地生成每个data 列表,如果您随后不向列表添加更多引用,它将是再次清除。
  • 好的,可以了!但是很慢......我猜是因为文件的大小。但有一件事很奇怪:如果我想加载一个元素(例如巴黎),它会非常非常慢(对于一个长数组)。更一般地说,即使你的解释很好,ijson 似乎也不是很快......
  • @JeanneDiderot:ijson 的默认后端是纯 python 解析器,它很慢。安装 YAJL 2.x 并使用 import ijson.backends.yajl2_cffi as ijson 导入更快的后端。
【解决方案2】:

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

【讨论】:

  • 不,我只想从 json 文件中加载数据列表;不是所有的 json 文件。问题是我有一个 500 Mo 文件,当我尝试加载所有内容时,python 返回一个“内存错误”。
【解决方案3】:

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

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

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

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

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

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

【讨论】:

  • 不,除非您还有更大的 JSON 文件。流式解析仍然是更好的选择。如果你愿意为此安装一个带有 Linux 的虚拟机,为什么不尝试使用 ijson 和 yajl 作为后端呢?
  • 因为这种方法的最大优点是最后你已经加载了文件。通常,当您进行数据处理时,您希望修改分析参数,如果您已经加载了文件,则速度会更快。之后,如果文件真的太大(超过几 GB),我会明确推荐您的方法。但是我的文件“只有 1-2 GB……而且我认为很多人都会问这个问题。
  • 无论如何,这并不是对 here 发布的问题的真正答案,这似乎与 ijson 库的使用有关。您正在回答“如何加载大型 JSON 文件”的问题,这个问题可能 导致 导致发布的实际问题。 :-)
  • 你显然是对的!我将您的答案重新列为最佳答案;)这显然是最完整的!
  • 谢谢,非常感谢。不仅对我来说,对以后可能来这里看看如何专门使用 ijson 的访问者也是如此。 :-)
猜你喜欢
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
  • 2018-10-18
  • 1970-01-01
  • 1970-01-01
  • 2019-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多