簡體   English   中英

如何將scipy.sparse矩陣與廣播的密集1d數組逐元素相乘?

[英]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.

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