2011-12-06 27 views
5

Tôi mới dùng python, đến từ MATLAB. Tôi có một ma trận thưa thớt lớn được lưu ở định dạng MATLAB v7.3 (HDF5). Tôi đã tìm thấy hai cách tải trong tệp bằng cách sử dụng h5pytables. Tuy nhiên hoạt động trên ma trận có vẻ rất chậm sau đó. Ví dụ, trong matlab:Đang tải ma trận thưa thớt Matlab được lưu với -7.3 (HDF5) vào Python và thao tác trên nó

>> whos  
    Name   Size     Bytes Class  Attributes 

    M  11337x133338   77124408 double sparse  

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

Sử dụng bảng:

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

Sử dụng h5py:

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

(Tôi đã bỏ chờ đợi ...)

[EDIT]

Dựa trên nhận xét từ @bpgergo, tôi nên thêm rằng tôi đã cố gắng chuyển đổi kết quả nạp bằng h5py (f) vào một mảng numpy hoặc một mảng thưa thớt scipy trong hai cách sau:

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

hoặc

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

nhưng cả hai hoạt động này đều rất chậm.

Có điều gì tôi thiếu ở đây không?

Trả lời

3

Hầu hết các vấn đề của bạn là bạn đang sử dụng python sum vào những gì có hiệu quả một mảng bộ nhớ ánh xạ (tức là nó trên đĩa, không có trong bộ nhớ).

Trước hết, bạn so sánh thời gian cần để đọc mọi thứ từ đĩa vào thời gian cần để đọc mọi thứ trong bộ nhớ. Load mảng vào bộ nhớ đầu tiên, nếu bạn muốn so sánh với những gì bạn đang làm trong MATLAB.

Thứ hai, nội dung của python sum rất không hiệu quả đối với mảng có nhiều mảng. (Hoặc, thay vào đó, lặp qua tất cả các mục của một mảng numpy độc lập là rất chậm, đó là những gì python's builtin sum đang làm.) Sử dụng numpy.sum(yourarray) hoặc yourarray.sum() thay cho mảng numpy.

Như một ví dụ:

(. Sử dụng h5py, bởi vì tôi là quen thuộc hơn với nó)

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

Tải tệp ở gần như tức thời trong Matlab (<1 giây) vì vậy tôi nghĩ việc so sánh là công bằng, nhưng tôi lấy điểm của bạn về hàm tổng tích hợp sẵn. Tôi nghĩ ngày càng nhiều người sẽ làm những gì tôi đang làm (chuyển từ Matlab sang Python) nên sẽ tốt hơn nếu có thêm một chút hỗ trợ để tải các tập tin Matlab IMHO ... – tdc

+1

Vâng, tôi không thể kiểm tra nó mà không cần tệp của bạn, nhưng thực sự tải mảng trong python cũng rất nhanh. Những gì bạn hiện đang làm không thực sự tải nó. Nó reutrns những gì có hiệu quả một mảng ánh xạ bộ nhớ. Truy cập nó một cách độc lập sẽ rất chậm trong bất kỳ ngôn ngữ nào, vì nó chủ yếu là tìm kiếm đĩa. Mã ví dụ trên vẫn còn chậm? Ngoài ra, hãy xem 'scipy.io.loadmat' http://docs.scipy.org/doc/scipy/reference/generated/scipy.io.loadmat.html#scipy.io.loadmat, mặc dù tôi không xem chắc chắn nếu nó hỗ trợ mảng thưa thớt. –

+0

chưa có cơ hội để thử nhưng nhờ đầu vào – tdc

0
+0

Bất kỳ nhiều manh mối? Nếu tôi làm 'M = numpy.asarray (f [" M "] [" dữ liệu "])' điều này dường như mất mãi mãi ... – tdc

+0

@tdc, tôi thậm chí không biết 'f' trong mã của bạn là gì. Hãy thử tham khảo trang này: http://docs.scipy.org/doc/scipy/reference/generated/scipy.io.loadmat.html. Mặc dù tôi đọc điều đó, bạn vẫn sẽ cần một lib python HDF5 để tải các tập tin Matlab v7.3. – bpgergo

+0

Cũng không có gì trên đó về ma trận thưa thớt – tdc

1

Câu trả lời chính thức cho hậu thế:

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 
Các vấn đề liên quan