numpy.square为稀疏矩阵返回不正确的结果

时间:2015-10-05 22:29:23

标签: python numpy scipy

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.

这是一个错误吗?

2 个答案:

答案 0 :(得分:2)

更新:正如hpaulj所指出的,其原因可能更为复杂。 np.square能够检测np.matrix并能够对元素进行平方。但是,它在sp.sparse.*matrix上停滞不前。

这不是一个错误;这是numpyscipy如何实现__mul__运算符之间的细微差别。默认情况下,* numpy.ndarray执行逐元素乘法,而numpy.matrix(因此,scipy.sparse.*matrix)执行矩阵乘法(来自PEP 465) :

  

numpy使用不同的__mul__方法提供两种不同的类型。对于   numpy.ndarray个对象,*执行元素乘法,和   矩阵乘法必须使用函数调用(numpy.dot)。对于   numpy.matrix个对象,*执行矩阵乘法,和   元素乘法需要函数语法。

在内部,numpy.square使用提供的参数的__mul__方法,该方法与ndarraymatrix es不同。

答案 1 :(得分:2)

通常,将scipy.sparse矩阵传入numpy函数,将数组(“array_like”)作为输入,导致未定义/意外行为。

没有自动sparse -> dense演员。

Numpy对Scipy的稀疏矩阵一无所知。

稀疏矩阵在Numpy理解的意义上不是“array_like”。 numpy函数然后做的是将稀疏矩阵视为一些未知类型的Python对象 - 通常导致将它们放入单元素对象数组,并从那里开始工作。对于返回标量结果,临时对象数组将被丢弃,只返回其中包含的对象,因此很容易错过实际完成的奇怪事情。

对象数组有一些回退用于对其元素(未知Python对象)执行算术等操作,包括在需要执行operator.mul时调用元素的*等等。然后将上述结果与您看到的行为相结合。