NumPy массивы с SQLite - PullRequest
       5

NumPy массивы с SQLite

5 голосов
/ 26 октября 2011

Самым распространенным интерфейсом SQLite, который я видел в Python, является sqlite3, но есть ли что-нибудь, что хорошо работает с массивами или повторными массивами NumPy?Под этим я подразумеваю тот, который распознает типы данных и не требует вставки строка за строкой, а извлекает в массив NumPy (rec) ...?Вроде как функции SQL R в библиотеках RDB или sqldf, если кто-то знаком с ними (они импортируют / экспортируют / добавляют целые таблицы или подмножества таблиц в или из таблиц данных R).

Ответы [ 4 ]

9 голосов
/ 28 октября 2011

почему бы не попробовать redis попробовать?

Доступны драйверы для двух интересующих вас платформ - python ( redis , через индекс пакета) 2 ) и R ( rredis , CRAN ).

Гений redis: , а не , он волшебным образом распознает тип данных NumPy и позволяет вставлять и извлекать многомерные массивы NumPy какесли они были родными типами данных redis, то скорее всего его гениальность заключается в удивительной легкости, с которой вы можете создать такой интерфейс с помощью всего лишь нескольких строк кода.

Существует (по крайней мере) несколько учебных пособий по redis в python;особенно хороша в блоге DeGizmo .

import numpy as NP

# create some data
A = NP.random.randint(0, 10, 40).reshape(8, 5)

# a couple of utility functions to (i) manipulate NumPy arrays prior to insertion 
# into redis db for more compact storage & 
# (ii) to restore the original NumPy data types upon retrieval from redis db
fnx2 = lambda v : map(int, list(v))
fnx = lambda v : ''.join(map(str, v))

# start the redis server (e.g. from a bash prompt)
$> cd /usr/local/bin      # default install directory for 'nix
$> redis-server           # starts the redis server

# start the redis client:
from redis import Redis
r0 = Redis(db=0, port=6379, host='localhost')       # same as: r0 = Redis()

# to insert items using redis 'string' datatype, call 'set' on the database, r0, and
# just pass in a key, and the item to insert
r0.set('k1', A[0,:])

# row-wise insertion the 2D array into redis, iterate over the array:
for c in range(A.shape[0]):
    r0.set( "k{0}".format(c), fnx(A[c,:]) )

# or to insert all rows at once
# use 'mset' ('multi set') and pass in a key-value mapping: 
x = dict([sublist for sublist in enumerate(A.tolist())])
r0.mset(x1)

# to retrieve a row, pass its key to 'get'
>>> r0.get('k0')
  '63295'

# retrieve the entire array from redis:
kx = r0.keys('*')           # returns all keys in redis database, r0

for key in kx :
    r0.get(key)

# to retrieve it in original form:
A = []
for key in kx:
    A.append(fnx2(r0.get("{0}".format(key))))

>>> A = NP.array(A)
>>> A
  array([[ 6.,  2.,  3.,  3.,  9.],
         [ 4.,  9.,  6.,  2.,  3.],
         [ 3.,  7.,  9.,  5.,  0.],
         [ 5.,  2.,  6.,  3.,  4.],
         [ 7.,  1.,  5.,  0.,  2.],
         [ 8.,  6.,  1.,  5.,  8.],
         [ 1.,  7.,  6.,  4.,  9.],
         [ 6.,  4.,  1.,  3.,  6.]])
3 голосов
/ 03 августа 2015

Предложение Дуга с redis довольно хорошо, но я думаю, что его код немного сложен и, как следствие, довольно медленный. Для моих целей мне пришлось сериализовать + записать, а затем схватить + десериализовать квадратную матрицу из примерно миллиона поплавков менее чем за одну десятую секунды, поэтому я сделал это:

Для записи:

snapshot = np.random.randn(1024,1024)
serialized = snapshot.tobytes()
rs.set('snapshot_key', serialized)

Тогда для чтения:

s = rs.get('snapshot_key')
deserialized = np.frombuffer(s).astype(np.float32)
rank = np.sqrt(deserialized.size).astype(int)
snap = deserialized(rank, rank)

Вы можете провести некоторое базовое тестирование производительности с помощью ipython, используя% времени, но ни тобайт, ни буфер не занимают более нескольких миллисекунд.

1 голос
/ 20 декабря 2012

Я нашел по крайней мере три пакета Python для интерфейса SQLite и NumPy :

Каждый из этих пакетов имеет дело с проблемой, что SQLite (по умолчанию) понимает только стандартные типы Python , а не типы данных NumPy , такие как numpy.int64.

RecSQL 0.7.8+ работает для меня (большую часть времени), но я считаю, что это довольно неудачный взлом и просмотр кода, esutil.sqlite_util кажется более зрелым.

1 голос
/ 24 августа 2012

Это выглядит немного старше, но есть ли причина, по которой вы не можете просто выполнить fetchall () вместо итерации, а затем просто инициализировать numpy при объявлении?

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