从大型 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 解决了这个问题,并且它有效。以下是这样做的主要步骤:
- 安装Virtual Box
- 安装Ubuntu(for exemple)
- 在您的计算机上安装 python for scientist,like SciPy
- 在 2 "computers" 之间创建共享文件(您将在 google 上找到教程)
- 在你的 ubuntu "computer" 上执行你的代码:它应该可以工作 ;)
注意:不要忘记为您的虚拟计算机提供足够的 RAM 和内存。
这对我有用。我再也没有这个 "memory error" 问题了。
所以,这是我的 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 解决了这个问题,并且它有效。以下是这样做的主要步骤:
- 安装Virtual Box
- 安装Ubuntu(for exemple)
- 在您的计算机上安装 python for scientist,like SciPy
- 在 2 "computers" 之间创建共享文件(您将在 google 上找到教程)
- 在你的 ubuntu "computer" 上执行你的代码:它应该可以工作 ;)
注意:不要忘记为您的虚拟计算机提供足够的 RAM 和内存。
这对我有用。我再也没有这个 "memory error" 问题了。