3

我正在学习使用 Numpy,我想查看数字列表求和的速度差异,所以我编写了以下代码:

np_array = numpy.arange(1000000)
start = time.time()
sum_ = np_array.sum()
print time.time() - start, sum_

>>> 0.0 1783293664

python_list = range(1000000)
start = time.time()
sum_ = sum(python_list)
print time.time() - start, sum_

>>> 0.390000104904 499999500000

python_list 总和是正确的。

如果我对总和为 1000 执行相同的代码,则两者都会打印正确的答案。Numpy 数组的长度是否有上限,还是与 Numpy sum 函数有关?

谢谢你的帮助

4

3 回答 3

9

当数字大于 32 位 int 时,标准列表切换到使用 long 类型进行算术运算。

numpy 数组没有切换到 long,并且遭受整数溢出。速度的代价是允许的值范围更小。

>>> 499999500000 % 2**32
1783293664L
于 2009-08-18T19:38:08.393 回答
9

Numpy 正在创建一个 32 位无符号整数数组。当它对它们求和时,它将它们求和成一个 32 位的值。

if 499999500000L % (2**32) == 1783293664L:
    print "Overflowed a 32-bit integer"

您可以在数组创建时显式选择数据类型:

a = numpy.arange(1000000, dtype=numpy.uint64)
a.sum() -> 499999500000
于 2009-08-18T19:40:03.693 回答
6

请注意,499999500000 % 2**32恰好等于 1783293664 ... 即,numpy 正在执行模 2**32 的运算,因为这是您告诉它使用的 numpy.array 的类型。

例如, Make np_array = numpy.arange(1000000, dtype=numpy.uint64),你的总和就会出来(当然仍然有限制,任何有限大小的数字类型)。

您可以dtype=numpy.object用来告诉 numpy 该数组包含通用 Python 对象;当然,随着通用性的增加,性能会下降。

于 2009-08-18T19:43:12.953 回答