在mongodb中保存numpy数组

时间:2011-06-16 05:43:11

标签: python mongodb numpy nosql

我有几个MongoDB文档,其中一个我的字段最好表示为矩阵(numpy数组)。我想将此文档保存到MongoDB,我该怎么做?

{
'name' : 'subject1',
'image_name' : 'blah/foo.png',
'feature1' : np.array(...)
}

6 个答案:

答案 0 :(得分:22)

对于1D numpy数组,您可以使用列表:

# serialize 1D array x
record['feature1'] = x.tolist()

# deserialize 1D array x
x = np.fromiter( record['feature1'] )

对于多维数据,我相信你需要使用pickle和pymongo.binary.Binary:

# serialize 2D array y
record['feature2'] = pymongo.binary.Binary( pickle.dumps( y, protocol=2) ) )

# deserialize 2D array y
y = pickle.loads( record['feature2'] )

答案 1 :(得分:4)

代码pymongo.binary.Binary(...)对我没有用,可能我们需要使用bson作为 @tcaswell建议。

无论如何这里是一个多维numpy数组的解决方案

>>from bson.binary import Binary
>>import pickle
# convert numpy array to Binary, store record in mongodb
>>record['feature2'] = Binary(pickle.dumps(npArray, protocol=2), subtype=128 )
# get record from mongodb, convert Binary to numpy array
>> npArray = pickle.loads(record['feature2'])

话虽如此,信用额转到MongoWrapper使用了他们写的代码。

答案 2 :(得分:4)

我们已经构建了一个开源库,用于在MongoDB中存储数字数据(Pandas,numpy等):

https://github.com/manahl/arctic

最重要的是,它非常易于使用,速度非常快,支持数据版本控制,多个数据库等。

答案 3 :(得分:2)

你试过Monary吗?

他们在网站上有例子

http://djcinnovations.com/index.php/archives/103

答案 4 :(得分:1)

你试试MongoWrapper,我觉得很简单:

声明与mongodb服务器和集合的连接以保存您的np。

import monogowrapper as mdb
db = mdb.MongoWrapper(dbName='test',
                      collectionName='test_collection', 
                      hostname="localhost", 
                      port="27017") 
my_dict = {"name": "Important experiment", 
            "data":np.random.random((100,100))}

字典就像你期望的那样:

print my_dict
{'data': array([[ 0.773217,  0.517796,  0.209353, ...,  0.042116,  0.845194,
         0.733732],
       [ 0.281073,  0.182046,  0.453265, ...,  0.873993,  0.361292,
         0.551493],
       [ 0.678787,  0.650591,  0.370826, ...,  0.494303,  0.39029 ,
         0.521739],
       ..., 
       [ 0.854548,  0.075026,  0.498936, ...,  0.043457,  0.282203,
         0.359131],
       [ 0.099201,  0.211464,  0.739155, ...,  0.796278,  0.645168,
         0.975352],
       [ 0.94907 ,  0.363454,  0.912208, ...,  0.480943,  0.810243,
         0.217947]]),
 'name': 'Important experiment'}

将数据保存到mongo:

db.save(my_dict)

要加载数据:

my_loaded_dict = db.load({"name":"Important experiment"})

答案 5 :(得分:0)

我知道这是一个老问题,但这是一个适用于新版本 pymongo 的优雅解决方案:

import pickle
from bson.binary import Binary, USER_DEFINED_SUBTYPE
from bson.codec_options import TypeCodec, TypeRegistry, CodecOptions
import numpy as np

class NumpyCodec(TypeCodec):
    python_type = np.ndarray
    bson_type = Binary

    def transform_python(self, value):
        return Binary(pickle.loads(value), USER_DEFINED_SUBTYPE)

    def transform_bson(self, value):
        if value.subtype == USER_DEFINED_SUBTYPE:
            return pickle.dumps(value, protocol=2)
        return value

def get_codec_options():
    numpy_codec = NumpyCodec()
    type_registry = TypeRegistry([numpy_codec])
    codec_options = CodecOptions(type_registry=type_registry)
    return codec_options

def get_collection(name, db):
    codec_options = get_codec_options()
    return db.get_collection(name, codec_options=codec_options)

然后你就可以这样收集了:

from pymongo import MongoClient
client = MongoClient()
db = client['my_db']
my_collection = get_collection('my_collection', db)

之后,您只需在数据库中透明地插入和查找 Numpy 数组即可。