np.sqrt对于非常大的整数的行为很奇怪

9
>>> np.__version__
'1.7.0'
>>> np.sqrt(10000000000000000000)
3162277660.1683793
>>> np.sqrt(100000000000000000000.)
10000000000.0
>>> np.sqrt(100000000000000000000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: sqrt

嗯...这里出现了 AttributeError: sqrt 的错误,是怎么回事呢?看起来 math.sqrt 没有相同的问题。


4
在这里学到了新东西。感谢发布! - mgilson
1个回答

10
最终的数字是一个“long”(Python中任意精度整数的名称),NumPy显然无法处理:
>>> type(100000000000000000000)
<type 'long'>
>>> type(np.int(100000000000000000000))
<type 'long'>
>>> np.int64(100000000000000000000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: Python int too large to convert to C long
AttributeError的出现是因为NumPy看到了一个它不知道如何处理的类型,就默认调用对象上的sqrt方法;但是这个方法并不存在。因此缺失的不是numpy.sqrt,而是long.sqrt
相比之下,math.sqrt知道long。如果您要在NumPy中处理非常大的数字,请尽可能使用浮点数。 编辑:好的,您正在使用Python 3。虽然在该版本中intlong之间的区别已经消失,但是NumPy仍然对可以使用PyLong_AsLong成功转换为C longPyLongObject和不能转换的对象之间的差异敏感。

1
但是,但是,这并不能解释AttributeError的原因...那么如何意外地从numpy命名空间中删除sqrt?这一定是个bug... - mgilson
@mgilson:我正要说到那个 :) - Fred Foo
(我确信这就是错误的原因——但这是一个非常奇怪的错误) - mgilson
哦,有趣。由于np.sqrt是一个ufunc,所以不会生成“正确”的回溯(因为异常是在C代码中引发的)。 - mgilson
实际上,我正在使用Python3,所以它们都是builtins.int - wim
错误信息已经得到改善 - TypeError: ufunc的循环不支持类型为int的参数0,该参数没有可调用的sqrt方法 - wim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接