python - numpy.reciprocal 在重复调用时返回不同的值

标签 python numpy floating-point

<分区>

我有一个 numpy 数组ssh_sum:

>>> ssh_sum
array([[ 0.,  2.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  2.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.,  2.]])

我想计算这个数组中元素的倒数。当我重复调用 np.reciprocal 时,Numpy 返回不同的值:

>>> ssh_sum
array([[ 0.,  2.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  2.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.,  2.]])
>>> np.reciprocal(ssh_sum, where=(ssh_sum > 0.))
array([[  6.90326535e-310,   5.00000000e-001,   1.00000000e+000,
          0.00000000e+000,   1.07034283e-296,   1.33666925e+241],
       [  4.74783847e-309,   1.45260789e-296,   1.00000000e+000,
          5.00000000e-001,   2.13436228e-287,  -3.13188338e-294],
       [  4.85105226e-309,   1.08690709e+171,   4.09521901e+149,
          1.00000000e+000,   2.82730247e-311,   5.00000000e-001]])
>>> np.reciprocal(ssh_sum, where=(ssh_sum > 0.))
array([[ inf,  0.5,  1. ,  inf,  inf,  inf],
       [ inf,  inf,  1. ,  0.5,  inf,  inf],
       [ inf,  inf,  inf,  1. ,  inf,  0.5]])
>>> np.reciprocal(ssh_sum, where=(ssh_sum > 0.))
array([[  6.90326535e-310,   5.00000000e-001,   1.00000000e+000,
          0.00000000e+000,   1.07034283e-296,   1.33666925e+241],
       [  4.74783847e-309,   1.45260789e-296,   1.00000000e+000,
          5.00000000e-001,   2.13436228e-287,  -3.13188338e-294],
       [  4.85105226e-309,   1.08690709e+171,   4.09521901e+149,
          1.00000000e+000,   2.82730247e-311,   5.00000000e-001]])
>>> np.reciprocal(ssh_sum, where=(ssh_sum > 0.))
array([[ inf,  0.5,  1. ,  inf,  inf,  inf],
       [ inf,  inf,  1. ,  0.5,  inf,  inf],
       [ inf,  inf,  inf,  1. ,  inf,  0.5]])

知道这里发生了什么吗?我使用的是 Python 3.4.5 和 numpy 1.13.3。

最佳答案

这不仅仅是互惠;使用 where 参数时会出现此问题。我已经能够使用 numpy 的主分支(np.__version__'1.15.0.dev0+c093997')重现该问题,其功能如 abs, sign, add, subtract

如果您仔细阅读 numpy“ufuncs”的文档字符串并正确解释它们,您会发现该行为不是错误。以下是 numpy.reciprocal 文档字符串中的相关描述:

out : ndarray, None, or tuple of ndarray and None, optional
    A location into which the result is stored. If provided, it must have
    a shape that the inputs broadcast to. If not provided or `None`,
    a freshly-allocated array is returned. A tuple (possible only as a
    keyword argument) must have length equal to the number of outputs.
where : array_like, optional
    Values of True indicate to calculate the ufunc at that position, values
    of False indicate to leave the value in the output alone.

请特别注意:

  • 哪里说“值 的 False 表示单独保留输出中的值。”
  • out 表示“如果未提供或, 返回一个新分配的数组。”

您没有提供 out 参数,因此通过调用 reciprocal 分配了一个新数组。这个数组的内容没有被初始化;该数组包含分配的内存中发生的所有内容。当您使用 where 参数时,只有输出中 where 为 True 的那些位置才被赋值。 where 为 False 的位置未被触及,因此它们保存数组分配时存在的任何随机内容。对于浮点输出,输出中的随机值可能是 0.04.85105226e-309 或任何其他随机值。

要按预期方式使用 where 参数,您还应该提供自己的 out 参数,并在输出 where where 中使用您想要的值进行初始化 为假。在您的情况下,您应该传入一个零数组:

In [84]: ssh_sum
Out[84]: 
array([[0., 2., 1., 0., 0., 0.],
       [0., 0., 1., 2., 0., 0.],
       [0., 0., 0., 1., 0., 2.]])

In [85]: out = np.zeros_like(ssh_sum)

In [86]: np.reciprocal(ssh_sum, where=ssh_sum > 0.0, out=out)
Out[86]: 
array([[0. , 0.5, 1. , 0. , 0. , 0. ],
       [0. , 0. , 1. , 0.5, 0. , 0. ],
       [0. , 0. , 0. , 1. , 0. , 0.5]])

In [87]: out
Out[87]: 
array([[0. , 0.5, 1. , 0. , 0. , 0. ],
       [0. , 0. , 1. , 0.5, 0. , 0. ],
       [0. , 0. , 0. , 1. , 0. , 0.5]])

关于python - numpy.reciprocal 在重复调用时返回不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49459985/

相关文章:

python - 在 PyQT/PySide 中设置窗口样式?

python matplotlib.pyplot 和 numpy 问题

python - Ubuntu 14.04 在没有 Root 访问权限的情况下安装 Numpy 和 Scipy

c# - 浮点变量的范围会影响它们的值吗?

objective-c - float 比较问题 objective-c

python - Pandas:修改特定级别的 Multiindex

python - celery 击败不接受周期性任务

python - 在 Python 中使用 OpenSSL 1.0.2(在 Travis CI OSX 图像上)?

python - 如何找到第一次出现的 Pandas 数据框值的显着差异?

c++ - 物理和 std::numeric_limits<double>::epsilon()...我们何时以及为何需要它?