Python Scipy稀疏:意外的身份行为
下面是我创建一个稀疏矩阵的尝试,该矩阵的对角线为Python Scipy稀疏:意外的身份行为,python,scipy,Python,Scipy,下面是我创建一个稀疏矩阵的尝试,该矩阵的对角线为c。我知道还有其他方法可以实现这一点,但我很好奇为什么下面的代码没有按预期工作: import numpy as np import scipy.sparse as sparse c = np.arange(0,5) >>> np.identity(5)*c array([[ 0., 0., 0., 0., 0.], [ 0., 1., 0., 0., 0.], [ 0., 0.,
c
。我知道还有其他方法可以实现这一点,但我很好奇为什么下面的代码没有按预期工作:
import numpy as np
import scipy.sparse as sparse
c = np.arange(0,5)
>>> np.identity(5)*c
array([[ 0., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 0., 2., 0., 0.],
[ 0., 0., 0., 3., 0.],
[ 0., 0., 0., 0., 4.]])
>>> sparse.identity(5)*c
array([ 0., 1., 2., 3., 4.])
#expected output:
<5x5 sparse matrix of type '<type 'numpy.float64'>'
with 5 stored elements (1 diagonals) in DIAgonal format>
# and (sparse.identity(5)*c).todense() == np.identity(5)*c
将numpy导入为np
将scipy.sparse导入为稀疏
c=np.arange(0,5)
>>>np.标识(5)*c
数组([[0,0,0,0,0,0.]),
[ 0., 1., 0., 0., 0.],
[ 0., 0., 2., 0., 0.],
[ 0., 0., 0., 3., 0.],
[ 0., 0., 0., 0., 4.]])
>>>三、身份(5)*c
数组([0,1,2,3,4.]))
#预期产出:
#和(稀疏标识(5)*c).todense()==np.identity(5)*c
在表达式sparse.identity(5)*c
中,使用稀疏矩阵的乘法运算符,即代数矩阵乘法(即矩阵乘以向量得到向量)
可以使用以下方法创建具有给定对角线的稀疏对角线矩阵:
[18]中的:来自scipy导入稀疏
在[19]中:c=np.arange(5)
In[20]:d=sparse.diags(c,0)
In[21]:d
出[21]:
在[22]中:d.A
出[22]:
数组([[0,0,0,0,0,0.]),
[ 0., 1., 0., 0., 0.],
[ 0., 0., 2., 0., 0.],
[ 0., 0., 0., 3., 0.],
[ 0., 0., 0., 0., 4.]])
数组乘法有两种常见类型:逐元素和矩阵
在MATLAB中,*
是矩阵版本,*
是逐元素的
在numpy中,*
是元素对元素(带有广播),“np.dot”是矩阵乘法的基本形式。Python开发人员已经批准将@
作为一种可以用于矩阵乘法的操作符(最终)
对于numpymatrix
子类,*
是矩阵乘法,np.multiply
用于元素对元素的乘法。(np.multiply
也适用于ndarray
)
scipy
遵循np.matrix
惯例*
是矩阵乘法sparse.identity(5).multiply(c)
执行元素对元素的乘法(尽管它返回np.matrix
,而不是稀疏矩阵)
至于原因,归根结底是开发人员习惯的惯例。对于线性代数问题,矩阵乘法很常见,因此在稀疏中使用np.matrix
复制MATLAB约定。创建MATLAB是为了访问FORTRAN矩阵库
在物理学中还有另一个惯例,爱因斯坦记法。这是一个广义矩阵乘法,扩展到更多维度<代码>np.einsum执行此操作。它可以实现元素对元素的乘法,尽管它的核心是使用“乘积之和”方法。但是对于np.matrix
或sparse
(实际上并不需要,因为它们总是二维的)
请注意,对于您的示例,规范是多么相似
np.einsum('ij,j->ij',np.identity(5),c) # element by element
np.einsum('ij,j->i',np.identity(5),c) # matrix (sum on j)
你能详细说明一下为什么使用这个操作符吗?这背后的原因是什么,用例是什么?这是我问题背后的重点,以理解其工作方式背后的逻辑。除了scipy稀疏类是矩阵类(不是numpy数组)之外,我不知道还能说些什么,稀疏矩阵代码的原始作者选择将*
实现为代数矩阵乘法。这并不是不合理的——只是不要将它们视为稀疏的numpy数组。Numpy还有一个(密集的)矩阵类(),该类还将*
定义为代数矩阵乘法。
np.einsum('ij,j->ij',np.identity(5),c) # element by element
np.einsum('ij,j->i',np.identity(5),c) # matrix (sum on j)