[英]numpy.square returns incorrect result for sparse matrices
将scipy.sparse
矩阵传递给它时, numpy.square
似乎给出了错误的输出:
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.
这是错误吗?
更新:正如hpaulj指出的,原因可能更多。 np.square
能够检测np.matrix
并能够对元素进行平方。 但是,它对sp.sparse.*matrix
。
这不是错误; 这是numpy
和scipy
如何实现__mul__
运算符之间的细微差别。 默认情况下, *
对于numpy.ndarray
执行numpy.ndarray
元素乘法,而对于numpy.matrix
(因此,对于scipy.sparse.*matrix
),它执行矩阵乘法(来自PEP 465 ):
numpy
提供了两种具有不同__mul__
方法的不同类型。 对于numpy.ndarray
对象,*
执行逐元素乘法,并且矩阵乘法必须使用函数调用(numpy.dot
)。 对于numpy.matrix
对象,*
执行矩阵乘法,而逐元素乘法则需要函数语法。
在内部, numpy.square
使用提供的参数的__mul__
方法,这对于ndarray
和matrix
是不同的。
通常,将scipy.sparse
矩阵传递scipy.sparse
数组(“ array_like”)为输入的numpy
函数,会导致未定义/意外的行为。
没有自动sparse -> dense
投射。
Numpy对Scipy的稀疏矩阵一无所知。
在Numpy理解的意义上,稀疏矩阵不是“类数组”。 然后,numpy函数要做的就是将稀疏矩阵仅视为某些未知类型的Python对象-通常将它们放到1个元素的对象数组中,然后从那里进行处理。 为了返回标量结果,将丢弃临时对象数组,而仅返回其中包含的对象,因此很容易错过实际已完成的操作。
对象数组在其元素(未知的Python对象)上执行算术等操作具有一些后备功能,包括如果需要执行*
则调用元素的operator.mul
等等。 然后将其与上述结果结合在一起,即可看到您的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.