簡體   English   中英

將稀疏數組中的元素與矩陣中的行相乘

[英]Multiplying elements in a sparse array with rows in matrix

如果您有一個稀疏矩陣 X:

>> X = csr_matrix([[0,2,0,2],[0,2,0,1]])
>> print type(X)    
>> print X.todense()    
<class 'scipy.sparse.csr.csr_matrix'>
[[0 2 0 2]
 [0 2 0 1]]

和一個矩陣 Y:

>> print type(Y)
>> print text_scores
<class 'numpy.matrixlib.defmatrix.matrix'>
[[8]
 [5]]

...如何將 X 的每個元素乘以 Y 的行。例如:

[[0*8 2*8 0*8 2*8]
 [0*5 2*5 0*5 1*5]]

要么:

[[0 16 0 16]
 [0 10 0 5]]

我已經厭倦了,但顯然它不起作用,因為尺寸不匹配: Z = X.data * Y

不幸的是,如果另一個矩陣是密集的,CSR 矩陣的.multiply方法似乎會使矩陣變得密集。 所以這將是避免這種情況的一種方法:

# Assuming that Y is 1D, might need to do Y = Y.A.ravel() or such...

# just to make the point that this works only with CSR:
if not isinstance(X, scipy.sparse.csr_matrix):
    raise ValueError('Matrix must be CSR.')

Z = X.copy()
# simply repeat each value in Y by the number of nnz elements in each row: 
Z.data *= Y.repeat(np.diff(Z.indptr))

這確實會創建一些臨時對象,但至少它是完全矢量化的,並且不會使稀疏矩陣變密。


對於 COO 矩陣,等效項為:

Z.data *= Y[Z.row] # you can use np.take which is faster then indexing.

對於 CSC 矩陣,等效項為:

Z.data *= Y[Z.indices]

我用來執行行(或列)乘法的方法是使用矩陣乘法和左側的對角矩陣(分別為右側):

import numpy as np
import scipy.sparse as sp

X = sp.csr_matrix([[0,2,0,2],
                   [0,2,0,1]])
Y = np.array([8, 5])

D = sp.diags(Y) # produces a diagonal matrix which entries are the values of Y
Z = D.dot(X) # performs D @ X, multiplication on the left for row-wise action

保留稀疏性(以 CSR 格式):

print(type(Z))
>>> <class 'scipy.sparse.csr.csr_matrix'>

輸出也是正確的:

print(Z.toarray()) # Z is still sparse and gives the right output
>>> print(Z.toarray()) # Z is still sparse and gives the right output
[[ 0. 16.  0. 16.]
 [ 0. 10.  0.  5.]]

我有同樣的問題。 我個人沒有發現scipy.sparse的文檔很有幫助,也沒有找到直接處理它的函數。 所以我試着自己寫,這為我解決了:

Z = X.copy()
for row_y_idx in range(Y.shape[0]):
    Z.data[Z.indptr[row_y_idx]:Z.indptr[row_y_idx+1]] *= Y[row_y_idx, 0]

這個想法是:對於位置row_y_idx -th 中Y每個元素,執行與Xrow_y_idx -th 行的標量乘法。 有關在此處訪問 CSR 矩陣中的元素的更多信息(其中dataAIAindptr )。

鑒於您定義的XY

import numpy as np
import scipy.sparse as sps

X = sps.csr_matrix([[0,2,0,2],[0,2,0,1]])
Y = np.matrix([[8], [5]])

Z = X.copy()
for row_y_idx in range(Y.shape[0]):
    Z.data[Z.indptr[row_y_idx]:Z.indptr[row_y_idx+1]] *= Y[row_y_idx, 0]

print(type(Z))
print(Z.todense())

輸出與您的相同:

<class 'scipy.sparse.csr.csr_matrix'>
 [[ 0 16  0 16]
  [ 0 10  0  5]]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM