从 JSON 文件到 Numpy 数组
Posted
技术标签:
【中文标题】从 JSON 文件到 Numpy 数组【英文标题】:From JSON file to Numpy Array 【发布时间】:2017-02-13 11:17:24 【问题描述】:我有一个 MongoDB 集合,当通过 PyMongo 导入 Python 时,它是 Python 中的一个字典。 我希望将其转换为 Numpy 数组。
例如,如果 JSON 文件如下所示:
"_id" : ObjectId("57065024c3d1132426c4dd53"),
"B" :
"BA" : 14,
"BB" : 23,
"BC" : 32,
"BD" : 41
"A" : 50,
"_id" : ObjectId("57065024c3d1132426c4dd53"),
"A" : 1
"B" :
"BA" : 1,
"BB" : 2,
"BC" : 3,
"BD" : 4
我想得到这个 5*2 Numpy Array 的回报: np.array([[50,14,23,32,41], [1,1,2,3,4]]) 在这种情况下,第一列对应“A”,第二列对应“BA”,第三列对应“BB”,以此类推。 请注意,键并不总是按相同的顺序排序。
我的代码根本不起作用(也没有做我想做的事)看起来像这样:
from pymongo import MongoClient
uri = "mongodb://localhost/test"
client = MongoClient(uri)
db=client.recodb
collection=db.recos
list1=list(collection.find())
array2=np.vstack([[product[key] for key in product.keys()] for product in list1])
【问题讨论】:
我不知道 MongoDB,但这不是一个有效的 JSON 对象。它应该是字典列表吗?此外,ObjectId("57065024c3d1132426c4dd53")
不是有效的 JSON 项:它应该被序列化为某种字符串,例如 "ObjectId(\"57065024c3d1132426c4dd53\")"
。
这就是文件在 RoboMongo 中的样子,我用它来可视化这个集合。
那么,'list1' 是一个字典列表。关于斜线,我不确定,但由于我最后没有使用,这并不重要。
MongoDB 以 BSON 格式存储数据,而不是普通的 json。这就是为什么那些 ObjectId 在那里的原因。不过这个问题应该没关系。
【参考方案1】:
flatdict 模块在使用 mongodb 数据结构时有时会很有用。它将为您处理扁平化嵌套字典结构:
columns = []
for d in data:
flat = flatdict.FlatDict(d)
del flat['_id']
columns.append([item[1] for item in sorted(flat.items(), key=lambda item: item[0])])
np.vstack(columns)
当然,不用flatdict也可以解决这个问题。
【讨论】:
您认为不使用“数据”循环就可以实现这一目标吗? 'data' 我实际上要使用 14000 个元素。 不确定您所说的不循环“数据”是什么意思。您可以做的一件事来提高速度(如果需要)是创建 numpy 数组作为您做的第一件事,然后将 mongodb 中的元素添加到该数组中。不过,我会先尝试该解决方案,以确保我过早地进行了优化。 我所说的循环数据的意思是:有没有办法在没有任何循环的情况下解决问题:for d in data
【参考方案2】:
假设您已成功将该 JSON 加载到 Python 中,这是创建所需 Numpy 数组的一种方法。我的代码具有ObjectId
的最小定义,因此它不会在ObjectId
条目上引发NameError。
sorted(d["B"].items())]
从“B”字典的内容中生成(键,值)元组列表,按键排序。然后,我们仅将这些元组中的值提取到一个列表中,并将该列表附加到包含“A”项中的值的列表中。
import numpy as np
class ObjectId(object):
def __init__(self, objectid):
self.objectid = objectid
def __repr__(self):
return 'ObjectId("")'.format(self.objectid)
data = [
"_id" : ObjectId("57065024c3d1132426c4dd53"),
"B" :
"BA" : 14,
"BB" : 23,
"BC" : 32,
"BD" : 41
,
"A" : 50
,
"_id" : ObjectId("57065024c3d1132426c4dd53"),
"A" : 1,
"B" :
"BA" : 1,
"BB" : 2,
"BC" : 3,
"BD" : 4
]
array2 = np.array([[d["A"]] + [v for _, v in sorted(d["B"].items())] for d in data])
print(array2)
输出
[[50 14 23 32 41]
[ 1 1 2 3 4]]
【讨论】:
以上是关于从 JSON 文件到 Numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章
将 numpy 数组列表转换为 json 以从烧瓶 api 返回