2016-10-05 65 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]]