2016-10-05 25 views
2

私はMongoDBコレクションを持っています。これはPyMongoを介してPythonにインポートされたとき、Pythonの辞書です。 Numpy Arrayに変換しようとしています。例えばJSONファイルからNumpy Arrayへ

、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]]) この場合、第1列は「A」に対応し、第2列は「BA」に対応し、第3列は"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) 

もちろん、これはフラットディックなしでも解決できます。

+0

'データ'のループを使わずにこれを達成することは可能だと思いますか? 'data'私は実際にコインタンズ14000要素を使用するつもりです。 – popuban

+0

'データ'にループしていないということをどういう意味か分かりません。スピードを上げるためにできることの1つは、必要な場合はまずnumpy配列を作成し、mongodbの要素をその配列に追加することです。私は最初に解決策を試してみたいと思いますが、私が早めに最適化していることを確認してください。 – freidrichen

+0

私がデータをループすることは、ループなしで問題を解決する方法があるかどうかです: 'for d in data' – popuban

1

PythonにそのJSONを正常に読み込んだとすると、必要なNumpy配列を作成する方法の1つがここにあります。私のコードは、ObjectIdの項目にNameErrorを発生させないように、最小定義はObjectIdです。

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]] 
関連する問題