[英]How to elementwise-multiply a scipy.sparse matrix by a broadcasted dense 1d array?
假設我有一個2d稀疏數組。 在我的實際用例中,行和列的數量都大得多(例如20000和50000),因此當使用密集表示時,它就無法容納在內存中:
>>> import numpy as np
>>> import scipy.sparse as ssp
>>> a = ssp.lil_matrix((5, 3))
>>> a[1, 2] = -1
>>> a[4, 1] = 2
>>> a.todense()
matrix([[ 0., 0., 0.],
[ 0., 0., -1.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 2., 0.]])
現在,假設我有一個密集的一維數組,其中所有非零分量的大小為3(在我的實際情況下為50000):
>>> d = np.ones(3) * 3
>>> d
array([ 3., 3., 3.])
我想使用通常的numpy廣播語義來計算a和d的元素乘法。 但是,scipy中的稀疏矩陣屬於np.matrix:'*'運算符被重載,以使其表現得像矩陣乘法而不是逐元素乘法:
>>> a * d
array([ 0., -3., 0., 0., 6.])
一種解決方案是使“ a”切換到“ *”運算符的數組語義,這將產生預期的結果:
>>> a.toarray() * d
array([[ 0., 0., 0.],
[ 0., 0., -3.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 6., 0.]])
但是我不能這樣做,因為對toarray()的調用將具體化不適合內存的'a'的密集版本(結果也將是密集的):
>>> ssp.issparse(a.toarray())
False
有什么想法如何在僅保留稀疏數據結構並且不必對'a'列進行無效python循環的情況下構建它?
我也在scipy.org進行了回復,但我認為我應該在此處添加答案,以防其他人在搜索時找到此頁面。
您可以將向量變成一個稀疏對角矩陣,然后使用矩陣乘法(帶有*)來完成與廣播相同的操作,但是效率很高。
>>> d = ssp.lil_matrix((3,3))
>>> d.setdiag(np.ones(3)*3)
>>> a*d
<5x3 sparse matrix of type '<type 'numpy.float64'>'
with 2 stored elements in Compressed Sparse Row format>
>>> (a*d).todense()
matrix([[ 0., 0., 0.],
[ 0., 0., -3.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 6., 0.]])
希望有幫助!
我認為A.multiply(B)應該稀疏工作。 該方法乘法執行“逐點”乘法,而不是矩陣乘法。
高溫超導
好吧,這是一個簡單的代碼,可以完成您想要的操作。 我不知道它是否像您想要的那樣高效,因此可以選擇保留還是保留它:
import scipy.sparse as ssp
def pointmult(a,b):
x = a.copy()
for i in xrange(a.shape[0]):
if x.data[i]:
for j in xrange(len(x.data[i])):
x.data[i] *= b[x.rows[i]]
return x
它僅適用於lil矩陣,因此如果要使其與其他格式一起使用,則必須進行一些更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.