【问题标题】:Power operator ** on numpy array returns a strange result. Is it a bug?numpy 数组上的幂运算符 ** 返回一个奇怪的结果。它是一个错误吗?
【发布时间】:2020-11-16 09:25:09
【问题描述】:

来自以下 Python 代码:

val = 499997
val**3

我得到了一个合理的结果:124997750013499973。

但是,从下面使用 numpy 的代码:

import numpy as np
val = 499997
np_val = np.arange(start=val, stop=val+1, dtype=np.uint64)
np_val**3

我得到了一个奇怪的结果,例如:array([124997750013499968], dtype=uint64)

是不是numpy的bug???

【问题讨论】:

  • 不,这不是错误,只是 64 位无符号整数的限制。 Python 的原生整数具有任意精度,它们不限于特定的位数。
  • @jonrsharpe 公平点。 OTOH,499997**3 的位长为 57,np_val * np_val * np_val 返回正确的值 124997750013499973。我的第一个猜测是 Numpy 可能正在使用日志进行求幂,但 np.uint64(np.exp(np.log(np_val) * 3)) 返回 124997750013500208。但是如果我转换为np.float96,例如np.uint64(np.exp(np.log(np.float96(np_val)) * 3)) 我得到了正确的结果。转换为 np.float64 与没有转换的结果相同。
  • @PM2Ring 嗯,有趣
  • >>> '%.3f' % 499997.0 ** 3 '124997750013499968.000'
  • @AnttiHaapala 回家吧,Numpy。你醉了! :) 这与np.uint64(np.float64(np_val) ** 3) 的答案相同。我想这比 np.uint64(np.float32(np_val) ** 3) 返回 124997747475480576 更好

标签: python numpy


【解决方案1】:

这似乎已在某个时候得到修复。现在在 NumPy 1.17.3 上尝试会产生正确的输出:

In [1]: import numpy as np 
   ...: val = 499997 
   ...: np_val = np.arange(start=val, stop=val+1, dtype=np.uint64) 
   ...: np_val**3 
   ...:
Out[1]: array([124997750013499973], dtype=uint64)

In [2]: np.__version__
Out[2]: '1.17.3'

该错误很可能是由某些 NumPy 实现代码转换为 float64 以执行操作然后再转换回导致的,因为这会产生错误的输出:

In [3]: np_val.astype(float)**3
Out[3]: array([1.2499775e+17])

In [4]: _.astype('uint64')
Out[4]: array([124997750013499968], dtype=uint64)

我无法找到该问题的修复提交或错误报告,但我确实找到了由该问题引起的 related bug report

【讨论】:

    【解决方案2】:

    这会产生垃圾:

    years      = np.arange(1980,2020)
    yeartothe3 = years**3 
    

    当这些工作时:

    years      = np.arange(1980,2020).astype(float)
    yeartothe3 = years**3 
    
    years      = np.arange(1980,2020)
    yeartothe3 = years**3.0
    

    一个真正的初学者陷阱......(叹气)

    【讨论】:

    • 这种行为的原因是什么?它是一个错误吗?这不回答任何问题。
    • 我不知道原因,但我希望这个观察有助于澄清事实并隔离问题。看起来 numpy 在纯整数增强方面存在问题。尽管在强制它使用浮点运算时它工作得很好。在github.com/numpy/numpy/issues?q=power+is%3Aissue+is%3Aopen+ 上进行了一些搜索,但没有找到相关的错误。
    猜你喜欢
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多