Direct multiplication of a dense array with a sparse matrix

If I have numpy.ndarray A and a scipy.sparse.csc_matrix B , how to take A dot B ? I can do B dot A by saying B.dot(A) , but otherwise I can only think about it:

 BTdot(AT).T 

Is there a more direct method to do this?

+5
source share
1 answer

Your question at first confused me, because for my version of scipy A.dot(B) and np.dot(A, B) both work fine; the sparse matrix .dot method simply overrides np.dot . However, it seems that this function has been added to this pull request and is not available in scipy versions older than 0.14.0. I assume you have one of these older versions.

Here are some test data:

 import numpy as np from scipy import sparse A = np.random.randn(1000, 2000) B = sparse.rand(2000, 3000, format='csr') 

For scipy versions> = 0.14.0 you can simply use:

 C = A.dot(B) C = np.dot(A, B) 

For versions <0.14.0 , both of them will raise the value of ValueError :

 In [6]: C = A.dot(B) --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-6-7fbaa337fd94> in <module>() ----> 1 C = A.dot(B) ValueError: Cannot find a common data type. 

Instead, you can use one of:

 # your original solution %timeit BTdot(AT).T # 10 loops, best of 3: 93.1 ms per loop # post-multiply A by B %timeit B.__rmul__(A) # 10 loops, best of 3: 91.9 ms per loop 

As you can see, there is basically no difference in performance, although I personally think the second version is more readable.


Update:

As @ shaoyl85 pointed out, you can simply use the * operator instead of directly calling the __rmul__() method:

 # equivalent to B.__rmul__(A) C = A * B 

Matrices seem to have higher priority in determining the behavior of the * operator than ndarrays. This is a potential opportunity for those of us who are more used to ndarrays (where * means elemental multiplication).

+3
source

All Articles