numpy.square
矩阵传递给它时, scipy.sparse
似乎提供了错误的输出:
import numpy as np
import scipy.sparse as S
a = np.array([np.arange(5), np.arange(5), np.arange(5), np.arange(5), np.arange(5)])
a
# array([[0, 1, 2, 3, 4],
# [0, 1, 2, 3, 4],
# [0, 1, 2, 3, 4],
# [0, 1, 2, 3, 4],
# [0, 1, 2, 3, 4]])
np.square(a)
# array([[ 0, 1, 4, 9, 16],
# [ 0, 1, 4, 9, 16],
# [ 0, 1, 4, 9, 16],
# [ 0, 1, 4, 9, 16],
# [ 0, 1, 4, 9, 16]])
b = S.lil_matrix(a)
c = np.square(b)
c
# <5x5 sparse matrix of type '<class 'numpy.int64'>'
# with 20 stored elements in Compressed Sparse Row format>
c[2,2]
# 20
# Expected output is 4, as in np.square(a) output above.
这是一个错误吗?
答案 0 :(得分:2)
更新:正如hpaulj所指出的,其原因可能更为复杂。 np.square
能够检测np.matrix
并能够对元素进行平方。但是,它在sp.sparse.*matrix
上停滞不前。
这不是一个错误;这是numpy
和scipy
如何实现__mul__
运算符之间的细微差别。默认情况下,*
numpy.ndarray
执行逐元素乘法,而numpy.matrix
(因此,scipy.sparse.*matrix
)执行矩阵乘法(来自PEP 465) :
numpy
使用不同的__mul__
方法提供两种不同的类型。对于numpy.ndarray
个对象,*
执行元素乘法,和 矩阵乘法必须使用函数调用(numpy.dot
)。对于numpy.matrix
个对象,*
执行矩阵乘法,和 元素乘法需要函数语法。
在内部,numpy.square
使用提供的参数的__mul__
方法,该方法与ndarray
和matrix
es不同。
答案 1 :(得分:2)
通常,将scipy.sparse
矩阵传入numpy
函数,将数组(“array_like”)作为输入,导致未定义/意外行为。
没有自动sparse -> dense
演员。
Numpy对Scipy的稀疏矩阵一无所知。
稀疏矩阵在Numpy理解的意义上不是“array_like”。 numpy函数然后做的是将稀疏矩阵视为一些未知类型的Python对象 - 通常导致将它们放入单元素对象数组,并从那里开始工作。对于返回标量结果,临时对象数组将被丢弃,只返回其中包含的对象,因此很容易错过实际完成的奇怪事情。
对象数组有一些回退用于对其元素(未知Python对象)执行算术等操作,包括在需要执行operator.mul
时调用元素的*
等等。然后将上述结果与您看到的行为相结合。