如果我有numpy.ndarray
A
和scipy.sparse.csc_matrix
B
,我该如何处理A
点B
?我可以通过说B
来A
点B.dot(A)
,但另一种方式我只能想到这一点:
B.T.dot(A.T).T
有更直接的方法吗?
答案 0 :(得分:3)
您的问题最初让我感到困惑,因为对于我的scipy版本,A.dot(B)
和np.dot(A, B)
都可以正常工作;稀疏矩阵的.dot
方法只会覆盖np.dot
。但是,似乎在this pull request中添加了此功能,并且在早于0.14.0的scipy版本中不存在此功能。我猜你有这些旧版本之一。
以下是一些测试数据:
import numpy as np
from scipy import sparse
A = np.random.randn(1000, 2000)
B = sparse.rand(2000, 3000, format='csr')
对于scipy> = 0.14.0 的版本,您只需使用:
C = A.dot(B)
C = np.dot(A, B)
对于版本< 0.14.0 ,这两个都会引发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.
相反,您可以使用以下方法之一:
# your original solution
%timeit B.T.dot(A.T).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
正如您所看到的,基本上没有性能差异,但我个人认为第二个版本更具可读性。
正如@ shaoyl85刚刚指出的那样,可以使用*
运算符而不是直接调用__rmul__()
方法:
# equivalent to B.__rmul__(A)
C = A * B
在确定*
运算符的行为时,矩阵似乎比ndarrays具有更高的优先级。对于我们这些更习惯于ndarrays行为的人来说,这是一个潜在的问题(其中*
表示元素乘法)。