Загрузка разреженной матрицы Matlab, сохраненной с -v7.3 (HDF5), в Python и работа над ней - PullRequest
5 голосов
/ 06 декабря 2011

Я новичок в python, пришедший из matlab.У меня есть большая разреженная матрица, сохраненная в формате Matlab v7.3 (HDF5).До сих пор я нашел два способа загрузки в файл, используя h5py и tables.Однако работа с матрицей, кажется, очень медленная после того, как.Например, в matlab:

>> whos     
  Name           Size                   Bytes  Class     Attributes

  M      11337x133338            77124408  double    sparse    

>> tic, sum(M(:)); toc
Elapsed time is 0.086233 seconds.

Использование таблиц:

t = time.time()
sum(f.root.M.data)
elapsed = time.time() - t
print elapsed
35.929461956

Использование h5py:

t = time.time()
sum(f["M"]["data"])
elapsed = time.time() - t
print elapsed

(я перестал ждать ...)

[EDIT]

Основываясь на комментариях @bpgergo, я должен добавить, что я пытался преобразовать результат, загруженный с помощью h5py (f), в массив numpy илиscipy разреженный массив двумя следующими способами:

from scipy import sparse
A = sparse.csc_matrix((f["M"]["data"], f["M"]["ir"], f["tfidf"]["jc"]))

или

data = numpy.asarray(f["M"]["data"])
ir = numpy.asarray(f["M"]["ir"])
jc = numpy.asarray(f["M"]["jc"])    
    A = sparse.coo_matrix(data, (ir, jc))

, но обе эти операции также чрезвычайно медленны.

Есть ли что-то, чего мне здесь не хватает?

Ответы [ 3 ]

3 голосов
/ 15 декабря 2011

Большая часть вашей проблемы заключается в том, что вы используете python sum в том, что фактически представляет собой отображаемый массив (т. Е. Он находится на диске, а не в памяти).

Прежде всего, вы сравниваете время, которое требуется для чтения информации с диска, со временем, которое требуется для чтения данных в памяти. Сначала загрузите массив в память, если вы хотите сравнить с тем, что вы делаете в Matlab.

Во-вторых, встроенные в Python sum очень неэффективны для массивов с пустым массивом. (Или, скорее, итерация по каждому элементу массива NumPy независимо очень медленная, что и делает встроенный в Python sum.) Используйте numpy.sum(yourarray) или yourarray.sum() вместо NUMPY массивов.

Как пример:

(Использование h5py, потому что я более знаком с ним.)

import h5py
import numpy as np

f = h5py.File('yourfile.hdf', 'r')
dataset = f['/M/data']

# Load the entire array into memory, like you're doing for matlab...
data = np.empty(dataset.shape, dataset.dtype)
dataset.read_direct(data)

print data.sum() #Or alternately, "np.sum(data)"
2 голосов
/ 15 декабря 2011

Окончательный ответ для потомков:

import tables, warnings
from scipy import sparse

def load_sparse_matrix(fname) :
    warnings.simplefilter("ignore", UserWarning) 
    f = tables.openFile(fname)
    M = sparse.csc_matrix( (f.root.M.data[...], f.root.M.ir[...], f.root.M.jc[...]) )
    f.close()
    return M
0 голосов
/ 06 декабря 2011

Тебе не хватает numy http://www.scipy.org/NumPy_for_Matlab_Users

...