In full gory detail:
In [19]: from scipy.sparse import csr_matrix
In [20]: row = [0, 1, 2]
...: col = [0, 0, 1]
...: value = [1, 2, 3]
...: x = csr_matrix((value, (row, col)), shape=[3, 3])
In [21]: x
Out[21]:
<3x3 sparse matrix of type '<class 'numpy.intc'>'
with 3 stored elements in Compressed Sparse Row format>
In [22]: np.array(x)
Out[22]:
array(<3x3 sparse matrix of type '<class 'numpy.intc'>'
with 3 stored elements in Compressed Sparse Row format>, dtype=object)
[22] is a 0d object dtype array. It is not x.A!
In [23]: w = np.random.normal(size=(3,2))
Multiplications where x controls the action, performing a proper multiplication. Operators delegate the work to argument methods.
In [24]: x*w
Out[24]:
array([[-1.64308263, -0.66048279],
[-3.28616526, -1.32096559],
[-2.9214839 , 1.70194911]])
In [25]: x@w
Out[25]:
array([[-1.64308263, -0.66048279],
[-3.28616526, -1.32096559],
[-2.9214839 , 1.70194911]])
dot function converts x to [22] and then does the multiplication:
In [26]: np.dot(x,w)
Out[26]:
array([[<3x3 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in Compressed Sparse Row format>,
<3x3 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in Compressed Sparse Row format>],
[<3x3 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in Compressed Sparse Row format>,
<3x3 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in Compressed Sparse Row format>],
[<3x3 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in Compressed Sparse Row format>,
<3x3 sparse matrix of type '<class 'numpy.float64'>'
with 3 stored elements in Compressed Sparse Row format>]],
dtype=object)
matmul does the same thing, but can't work with scalars (which is what [22] is):
In [27]: np.matmul(x,w)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [27], in <cell line: 1>()
----> 1 np.matmul(x,w)
ValueError: matmul: Input operand 0 does not have enough dimensions (has 0, gufunc core with signature (n?,k),(k,m?)->(n?,m?) requires 1)
From the main sparse docs page, https://docs.scipy.org/doc/scipy/reference/sparse.html
Warning
As of NumPy 1.7, np.dot is not aware of sparse matrices, therefore
using it will result on unexpected results or errors. The
corresponding dense array should be obtained first instead:
np.dot(A.toarray(), v)
array([ 1, -3, -1], dtype=int64)
but then all the performance advantages would be lost.
and
Despite their similarity to NumPy arrays, it is strongly discouraged
to use NumPy functions directly on these matrices because NumPy may
not properly convert them for computations, leading to unexpected
(and incorrect) results.