2014-04-27 39 views
2

看起來numpy的einsum函數不適用於scipy.sparse矩陣。 einsum可以用稀疏矩陣進行各種各樣的事情嗎?稀疏矩陣上的唯一性

回覆@ eickenberg的回答:我想要的特定義務是numpy.einsum("ki,kj->ij",A,A) - 這些行的外部產品的總和。

+1

是的,有替代品,但沒有一般的 「疏einsum」。這取決於你需要做什麼。 –

回答

2

scipy.sparse矩陣的一個限制是它們代表線性算子,因此保持二維,這導致了一個問題:您在尋找哪種操作?

在一對2D矩陣的所有einsum操作是非常容易的,而不使用dottranspose和逐點操作einsum寫,只要該結果不超過兩個維度。

因此,如果您需要對多個稀疏矩陣進行特定操作,則可能無需編寫einsum

UPDATE:執行np.einsum("ki, kj -> ij", A, A)的具體方法是A.T.dot(A)。爲了說服自己,請嘗試以下示例:

import numpy as np 
rng = np.random.RandomState(42) 
a = rng.randn(3, 3) 
b = rng.randn(3, 3) 
the_einsum_ab = np.einsum("ki, kj -> ij", a, b) 
the_a_transpose_times_b = a.T.dot(b) 
# We write a test in order to assert equality 
from numpy.testing import assert_array_equal 
assert_array_equal(the_einsum_ab, the_a_transpose_times_b) # This passes, so equality 

此結果略爲一般。現在,如果您使用b = a,您將獲得您的特定結果。

+1

我已經爲這個問題添加了一個具體的例子。 – drevicko

+0

謝謝,我在更新中解決了它。這對你有用嗎? – eickenberg

+0

是的,當你想到它時真的很明顯!謝謝 (: – drevicko

2

einsum將索引字符串轉換爲使用C版本np.nditer的計算。 http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html是一個很好的介紹nditer。最後請注意Cython示例。

https://github.com/hpaulj/numpy-einsum/blob/master/einsum_py.pyeinsum的Python模擬。

scipy.sparse有自己的代碼(最終在C中)執行基本操作,求和,矩陣乘法等。稀疏矩陣有它們自己的數據結構。它們可以是列表,字典或一組numpy數組。可以使用Numpy符號,因爲sparse具有合適的__xxx__方法。

稀疏矩陣是一個matrix,一個2d數組對象。可以編寫一個稀疏的einsum,但最終會使用稀疏矩陣乘法,而不是nditer。所以最好這是一個符號方便。

稀疏csr_matrix.dot是:

def dot(self, other): 
    """Ordinary dot product 
    ... 
    """ 
    return self * other 

A=sparse.csr_matrix([[1,2],[3,4]]) 
A.dot(A.T).A 
(A*A.T).A 
A.__rmul__(A.T).A 
A.__mul__(A.T).A 
np.einsum('ij,kj',A.A,A.A) 
# array([[ 5, 11], 
#  [11, 25]])