2014-09-19 4 views
0

У меня есть таблица в MySQL с тремя столбцами: индекс строки, индекс столбца и значение, которое я хочу прочитать в scipy csr_matrix. Я использую соединитель Python-MySQL. Есть 112 500 ненулевых элементов.Эффективно читать разреженную матрицу Python из SQL

Попробуйте 1:

A = csr_matrix((N_rows, N_cols), dtype=float) 
show = 'SELECT * FROM my_table' 
cursor.execute(show) 
for (row, col, value) in cursor: 
    A[row, col] = value 

Это слишком медленно, я должен был остановить его через 60 секунд. Он упомянул о предупреждении эффективности и предложил использовать матрицы lil.

Попытка 2:

A = lil_matrix((N_rows, N_cols), dtype=float) 
show = 'SELECT * FROM my_table' 
cursor.execute(show) 
for (row, col, value) in cursor: 
    A[row, col] = value 
A = csr_matrix(A) 

Это занимает 6,4 секунд (среднее значение из трех). Это так хорошо, как получается, или есть более быстрый способ, с помощью которого я могу создать csr_matrix, не пройдя цикл? Если я выполняю cursor.fetchall(), данные выглядит следующим образом:

[(row_0, col_0, value_0), (row_1, col_1, value_1), ...] 

Это не может быть использован для конструктора csr_matrix.

ответ

4

Данные, возвращаемые cursor.fetchall(), почти в формате coo_matrix. Вы можете сделать

import numpy as np 
from scipy.sparse import coo_matrix 

data = cursor.fetchall() 
#data = [(1, 2, 1.2), (3, 4, 7.1)] 

arr = np.array(data, dtype=[('row', int), ('col', int), ('value', float)]) 
spmat = coo_matrix((arr['value'], (arr['row'], arr['col']))) 

Вместо np.array(cursor.fetchall(), ...) можно также предпочтительно использовать

arr = np.fromiter(cursor, dtype=[('row', int), ('col', int), ('value', float)]) 

для загрузки данных из БД непосредственно в массив Numpy.

+0

Большинство разреженных форматов принимают входные данные в стиле '(value, (row, col))'. Реализация, вероятно, сначала создает 'coo', а затем преобразует ее в' csr' (или что-то еще). – hpaulj

+0

Спасибо за подсказку с coo. Ваше решение с данными = fetchall() и np.array (data, ...) возвращает время чтения до 5,5 секунд. Однако второе решение, использующее np.fromiter, снова возвращает время считывания, до 6,9 секунд (все средние значения 6 раз). – physicalattraction

+0

Скорость, вероятно, ограничена тем, насколько быстро интерфейс БД Python может вытащить данные из БД или даже по скорости самого механизма БД. Возможно, возможно ускорить процесс, если формат, который матрица хранится в БД, может быть изменен, например. сохраняя его как необработанные двоичные данные. –

Смежные вопросы