2011-07-27 67 views
26

Tôi đang làm việc với một số ma trận thưa thớt khá lớn (từ 5000x5000 đến 20000x20000) và cần tìm một cách hiệu quả để nối ma trận một cách linh hoạt để xây dựng ma trận ngẫu nhiên từ các phần riêng biệt.Có cách nào hiệu quả để ghép các ma trận scipy.sparse không?

Ngay bây giờ tôi đang sử dụng cách sau đây để nối bốn ma trận, nhưng nó không hiệu quả khủng khiếp. Có cách nào tốt hơn để làm điều này mà không liên quan đến việc chuyển đổi thành một ma trận dày đặc?

rmat[0:m1.shape[0],0:m1.shape[1]] = m1 
rmat[m1.shape[0]:rmat.shape[0],m1.shape[1]:rmat.shape[1]] = m2 
rmat[0:m1.shape[0],m1.shape[1]:rmat.shape[1]] = bridge 
rmat[m1.shape[0]:rmat.shape[0],0:m1.shape[1]] = bridge.transpose() 

Trả lời

14

OK, tôi đã tìm thấy câu trả lời. Sử dụng scipy.sparse.coo_matrix nhanh hơn nhiều so với sử dụng lil_matrix. Tôi chuyển đổi các ma trận thành coo (không đau và nhanh) và sau đó chỉ cần ghép nối dữ liệu, các hàng và cột sau khi thêm phần đệm bên phải.

data = scipy.concatenate((m1S.data,bridgeS.data,bridgeTS.data,m2S.data)) 
rows = scipy.concatenate((m1S.row,bridgeS.row,bridgeTS.row + m1S.shape[0],m2S.row + m1S.shape[0])) 
cols = scipy.concatenate((m1S.col,bridgeS.col+ m1S.shape[1],bridgeTS.col ,m2S.col + m1S.shape[1])) 

scipy.sparse.coo_matrix((data,(rows,cols)),shape=(m1S.shape[0]+m2S.shape[0],m1S.shape[1]+m2S.shape[1])) 
+1

Cảm ơn bạn đã quay lại và nhận xét về cách bạn đã thực hiện nhanh chóng. Tôi cần nó cho lớp NLP của tôi. – placeybordeaux

42

Thư viện thưa thớt nay đã có hstackvstack cho tương ứng concatenating ma trận theo chiều ngang và theo chiều dọc.

+1

Đảm bảo bạn sử dụng scipy.sparse.hstack thay vì numpy.hstack – 0111001101110000

9

Sử dụng hstack, vstack hoặc concatenate, chậm hơn đáng kể so với việc ghép chính các đối tượng dữ liệu bên trong. Lý do là hstack/vstack chuyển đổi ma trận thưa thớt thành định dạng coo có thể rất chậm khi ma trận là rất lớn và không có định dạng coo. Dưới đây là mã để ghép các ma trận csc, phương pháp tương tự có thể được sử dụng cho các ma trận csr:

def concatenate_csc_matrices_by_columns(matrix1, matrix2): 
    new_data = np.concatenate((matrix1.data, matrix2.data)) 
    new_indices = np.concatenate((matrix1.indices, matrix2.indices)) 
    new_ind_ptr = matrix2.indptr + len(matrix1.data) 
    new_ind_ptr = new_ind_ptr[1:] 
    new_ind_ptr = np.concatenate((matrix1.indptr, new_ind_ptr)) 

    return csc_matrix((new_data, new_indices, new_ind_ptr)) 
+1

Chỉ cần xem xét một cách nhanh chóng để thêm hàng mới vào ma trận CSR. Đây chính xác là những gì tôi cần. Cảm ơn @amos. – singleton

+0

Nếu bạn sử dụng phương pháp này, bạn cần phải xác định hình dạng trong 'return csc_matrix ((new_data, new_indices, new_ind_ptr))' tức là: 'return csc_matrix ((new_data, new_indices, new_ind_ptr), shape = (matrix1.shape [1], matrix1.shape [1] + matrix2.shape [1]) ' – simeon

4

Câu trả lời của Amos không còn cần thiết nữa. Scipy bây giờ làm một cái gì đó tương tự như nội bộ này nếu ma trận đầu vào có định dạng csr hoặc csc và định dạng đầu ra mong muốn được đặt thành không có hoặc định dạng giống như ma trận đầu vào. Đó là hiệu quả để theo chiều dọc chồng ma trận ở định dạng csr, hoặc để theo chiều ngang chồng ma trận ở định dạng csc, sử dụng scipy.sparse.vstack hoặc scipy.sparse.hstack, tương ứng.

+0

Phiên bản nào hiện "tham chiếu"? Bạn có bất kỳ tham chiếu nào cho điều này không? – lenz

+0

Mã có liên quan là [đoạn mã này] (https://github.com /scipy/scipy/blob/master/scipy/sparse/construct.py#L552) từ 'scipy.sparse.bmat', cả hai sử dụng' vstack' và 'hstack'. Bản hack này ban đầu được thêm vào [đây] (https: //github.com/scipy/scipy/commit/10b2cbdc980c6e1695c732c90fba99f722437171) vào năm 2013. Có vẻ như ban đầu nó được bao gồm trong scipy 1.0.0. –

+0

Cảm ơn! Scipy 1.0.0 vẫn đang ở giai đoạn RC, mặc dù ... – lenz

Các vấn đề liên quan