为什么numpy.prod()错误地为我的长自然数列表返回否定结果或0?

Ben*_*ley 8 python math numpy list

我正在研究Project Euler 问题12,因此我需要针对超过500个独特因子的倍数进行一些测试.

我认为数组[1,2,3 ... 500]将是一个很好的起点,因为该数组的乘积是可能的最低数字.但是,numpy.prod()为此数组返回.我确定我错过了一些明显的东西,但到底是什么?

>>> import numpy as np
>>> array = []
>>> for i in range(1,100):
...   array.append(i)
... 
>>> np.prod(array)
0
>>> array.append(501)
>>> np.prod(array)
0
>>> array.append(5320934)
>>> np.prod(array)
0
Run Code Online (Sandbox Code Playgroud)

Ami*_*ory 6

请注意,Python使用“无限”整数,但是在numpy中,所有类型都被键入,因此这里是“ C”风格(可能是64位)整数。您可能正在经历溢出。

如果查看的文档numpy.prod,则可以看到dtype参数:

返回数组的类型,以及与元素相乘的累加器的类型。

您可以做几件事:

  1. 回到Python,并使用其“无限整数”相乘(有关方法,请参阅此问题)。

  2. 考虑您是否真的需要找到如此庞大的产品。通常,当您使用非常小或非常大的乘积时,会切换到对数和。正如@WarrenWeckesser所指出的,这显然是不精确的(这不像最后采用指数会为您提供确切的解决方案)-而是用来衡量一种产品是否比另一种产品增长更快。

  • 使用`float`s将失去精度。 (2认同)

wim*_*wim 5

这些数字变得非常大,速度很快.

>>> np.prod(array[:25])
7034535277573963776
>>> np.prod(array[:26])
-1569523520172457984
>>> type(_)
numpy.int64
Run Code Online (Sandbox Code Playgroud)

你实际上在这里溢出nu​​mpy的数据类型,因此wack结果.如果你坚持使用python ints,你就不会有溢出.

>>> import operator
>>> reduce(operator.mul, array, 1)
933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000L
Run Code Online (Sandbox Code Playgroud)