numpy: есть ли драйвер для загрузки данных с mongodb? - PullRequest
1 голос
/ 31 марта 2012
  • У меня есть большая коллекция в монго
  • Я хочу загрузить данные в numpy ndarray
  • есть ли способ загрузить данные из mongodb без итерации через pymongo. что-то вроде R-Mongo

1 Ответ

0 голосов
/ 31 марта 2012

Есть несколько предположений, которые относятся к этому, большинство из которых относятся к "схеме" ваших документов.В зависимости от того, насколько четко это определено, то есть степень вложенности, ожидаемый тип и количество ключей и т. Д., Вы можете использовать ярлыки для преобразования вашей коллекции в ноль rec.array.Поэтому я постараюсь сосредоточиться больше на подходе, а не на освещении всех возможных случаев конверсии, чтобы дать вам представление о том, как начать.Например, для монго-документа, который выглядит следующим образом:

tdict = {'A': 151,
         'B': 'somestring',
         'C': [1, 2, 3],
         '_id': ObjectId('4edd4e4367fbe05022000034')}

или список таких документов:

tlist = [{'A': 151,
          'B': 'somestring',
          'C': [1, 2, 3],
          '_id': ObjectId('4edd4e4367fbe05022000034')},
         {'A': 151,
          'B': 'somestring',
          'C': [1, 2, 3],
          '_id': ObjectId('4edd4e4367fbe05022000034')}]

Функция, которая может использоваться для преобразования этого списка в numyrec.array может выглядеть следующим образом:

import numpy as n

def DictToRecArray(data, columnNames=[]):
    result = None

    if data and isinstance(data, list) or isinstance(data, dict):
        data = [data] if isinstance(data, dict) else data
        if isinstance(data[0], dict):
            columnNames = map(str, data[0].keys()) if not columnNames else columnNames
            columns = [(str(c), type(data[0][c])) for c in columnNames]
            for i,clm in enumerate(columns):
                if clm[1].__name__ in ['str','unicode']:
                    maxlen = 0
                    for row in data:                    
                        maxlen = len(row[clm[0]]) if len(row[clm[0]]) > maxlen else maxlen
                    columns[i] = (clm[0], n.dtype('S%d' % maxlen,1))

            result = n.recarray((len(data)),dtype=columns)
            c_order = [c[0] for c in columns]
            for i,row in enumerate(data):
                for c in c_order:        
                    result[i][c] = row[c]

    return result

с columnNames, позволяющим выбрать ключи из ваших документов, которые будут использоваться при генерации rec.array, а также определить порядок этих ключей в виде столбцовв самом rec.array.

Мой предыдущий пункт о предположениях становится очевидным, если вы потратите некоторое время на рассмотрение реализации DictToRecArray.Например, я мог бы рассматривать наличие значения list как возможность развернуть документ в несколько строк в пределах rec.array, то есть для ключа C в tDict я мог бы продублировать значения ключей A, B и _id и генерируем результирующее rec.array с формой, равной (3,) против (1,).Пройдя по этому пути, вы увидите, что реализация DictToRecArray будет тесно связана с вашей «схемой», и моя реализация может затормозить некоторые ваши документы.Тем не менее, в этом случае передача tlist в DictToRecArray приводит к:

rec.array([(151, [1, 2, 3], 'somestring', ObjectId('4edd4e4367fbe05022000034')),
       (151, [1, 2, 3], 'somestring', ObjectId('4edd4e4367fbe05022000034'))], 
      dtype=[('A', '<i8'), ('C', '|O8'), ('B', '|S10'), ('_id', '|O8')])

Учитывая, что вы искали результат типа data.frame, rec.array должен хорошо вам служить,Надеюсь, что это приведет вас на правильный путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...