2011-12-06 2 views
5

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

>> 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

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

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

Во-вторых, встроенный python sum очень неэффективен для массивов numpy. (Или, вернее, итерация через каждый элемент массива 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)" 
+0

Загрузка файла была почти мгновенной в Matlab (<1сек), поэтому я считаю, что сравнение было справедливым, но я хочу сказать о встроенной функции sum. Я думаю, что все больше и больше людей будут делать то, что я делаю (переход от Matlab к Python), поэтому было бы хорошо, если бы было немного больше поддержки для загрузки в файлах Matlab IMHO ... – tdc

+1

Ну, я не могу протестируйте его без вашего файла, но на самом деле загрузка массива в python также должна быть очень быстрой. То, что вы сейчас делаете, на самом деле не загружает его. Он повторяет то, что эффективно представляет собой массив с памятью. Доступ к нему независимо будет очень медленным на любом языке, так как он в основном работает с дисками. Является ли приведенный выше примерный код еще медленным? Кроме того, посмотрите на 'scipy.io.loadmat' http://docs.scipy.org/doc/scipy/reference/generated/scipy.io.loadmat.html#scipy.io.loadmat, хотя я не если он поддерживает разреженные массивы. –

+0

еще не успел попробовать, но спасибо за вход – tdc

0

Вы упускаете Numpy http://www.scipy.org/NumPy_for_Matlab_Users

+0

Любые дополнительные подсказки? Если я делаю 'M = numpy.asarray (f [" M "] [" data "]), это кажется навсегда ... – tdc

+0

@tdc, я даже не знаю, что такое' f' в вашем коде. Попробуйте обратиться на эту страницу: http://docs.scipy.org/doc/scipy/reference/generated/scipy.io.loadmat.html. Хотя я читал это, вам все равно понадобится HDF5 python lib для загрузки файлов Matlab v7.3. – bpgergo

+0

Также нет ничего о разреженных матрицах – tdc

1

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

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 
Смежные вопросы