2016-10-05 73 views
2

我有一个MongoDB集合,它在通过PyMongo导入到Python时是Python中的一个词典。 我期待将其转换为Numpy数组。从JSON文件到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的阵列: np.array([50 ,14,23,32,41], [1,1,2,3,4]]) 在这种情况下,第一列对应于“A”,第二列对应于“BA”,第三个对应“BB”等。 注意,密钥并不总是按照相同的顺序排序。

我的代码,这并不在所有的工作(并没有做什么,我想还没有)看起来是这样的:用MongoDB的数据结构中工作时

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]) 
+0

我不知道MongoDB的,但不是有效的JSON对象。它应该是一个字典列表吗?此外,'ObjectId(“57065024c3d1132426c4dd53”)'不是有效的JSON项目:它应该被序列化为某种字符串,例如''ObjectId(\“57065024c3d1132426c4dd53 \”)“'。 –

+0

这是文件在RoboMongo中的外观,我用它来查看这个集合。 – popuban

+0

然后,'list1'是一个词典列表。关于斜线,我不确定,但由于我最终没有使用,所以它并不重要。 – popuban

回答

1

flatdict模块有时是有用的。它将处理拼合你的嵌套字典结构:

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了。

+0

您是否可以在不使用'data'循环的情况下实现这一点? 'data'我实际上会使用cointains 14000个元素。 – popuban

+0

不确定你的意思是不循环'数据'。你可以做的一件事是提高速度(如果需要的话),首先要创建numpy数组,然后将mongodb中的元素添加到该数组中。我会尽可能地尝试解决方案,以确保我过早地进行了优化。 – freidrichen

+0

我的意思是循环数据是:有没有办法解决这个问题,没有任何循环:'对于数据' – popuban

1

假设您已经成功将该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]]