在numpy数组中对元素进行平方时的奇怪行为

时间:2016-04-08 04:35:06

标签: python arrays numpy sqrt

我有两个numpy形状阵列(1,250000):

a = [[  0 254   1 ..., 255   0   1]]
b = [[  1   0 252 ...,   0 255 255]]

我想创建一个新的numpy数组,其元素是数组ab中元素的平方和的平方根,但我得不到正确的结果:

>>> c = np.sqrt(np.square(a)+np.square(b))
>>> print c
[[ 1.          2.          4.12310553 ...,  1.          1.          1.41421354]]

我在这里错过了一些简单的东西吗?

2 个答案:

答案 0 :(得分:5)

大概你的数组ab是无符号8位整数的数组 - 你可以通过检查属性a.dtype来检查。对它们进行平方时,数据类型将被保留,并且8位值会溢出,这意味着值"环绕" (即平方值为模256):

In [7]: a = np.array([[0, 254, 1, 255, 0, 1]], dtype=np.uint8)

In [8]: np.square(a)
Out[8]: array([[0, 4, 1, 1, 0, 1]], dtype=uint8)

In [9]: b = np.array([[1, 0, 252, 0, 255, 255]], dtype=np.uint8)

In [10]: np.square(a) + np.square(b)
Out[10]: array([[ 1,  4, 17,  1,  1,  2]], dtype=uint8)

In [11]: np.sqrt(np.square(a) + np.square(b))
Out[11]: 
array([[ 1.        ,  2.        ,  4.12310553,  1.        ,  1.        ,
         1.41421354]], dtype=float32)

为避免此问题,您可以告诉np.square使用浮点数据类型:

In [15]: np.sqrt(np.square(a, dtype=np.float64) + np.square(b, dtype=np.float64))
Out[15]: 
array([[   1.        ,  254.        ,  252.00198412,  255.        ,
         255.        ,  255.00196078]])

您也可以使用函数numpy.hypot,但您可能仍希望使用dtype参数,否则默认数据类型为np.float16

In [16]: np.hypot(a, b)
Out[16]: array([[   1.,  254.,  252.,  255.,  255.,  255.]], dtype=float16)

In [17]: np.hypot(a, b, dtype=np.float64)
Out[17]: 
array([[   1.        ,  254.        ,  252.00198412,  255.        ,
         255.        ,  255.00196078]])

您可能想知道为什么我在dtypenumpy.square中使用的numpy.hypot参数未显示在函数'文档字符串。这两个函数都是numpy "ufuncs",而numpy的作者认为最好只显示docstring中的主要参数。可选参数是documented in the reference manual

答案 1 :(得分:0)

对于这个简单的案例,它完全正常:

In [1]: a = np.array([[ 0, 2, 4, 6, 8]])
In [2]: b = np.array([[ 1, 3, 5, 7, 9]])
In [3]: c = np.sqrt(np.square(a) + np.square(b))

In [4]: print(c)
[[  1.     3.60555128   6.40312424   9.21954446  12.04159458]]

你一定做错了。