1

我对 NumPy 完全陌生,并尝试了教科书代码。不幸的是,在一定规模的计算中,NumPy 结果被搞砸了。这是代码:

import sys
from datetime import datetime
import numpy

def pythonsum(n):
    a = range(n)
    b = range(n)
    c = []
    for i in range(len(a)):
        a[i] = i**2
        b[i] = i**3
        c.append(a[i]+b[i])
    return c

def numpysum(n):
    a = numpy.arange(n) ** 2
    b = numpy.arange(n) ** 3
    c = a + b
    return c

size = int(sys.argv[1])
start = datetime.now()
c=pythonsum(size)
delta = datetime.now()-start
print "The last 2 elements of the sum",c[-2:]
print "PythonSum elapsed time in microseconds", delta.microseconds
start = datetime.now()
c=numpysum(size)
delta = datetime.now()-start
print "The last 2 elements of the sum",c[-2:]
print "NumPySum elapsed time in microseconds", delta.microseconds

当 size >= 1291 时结果为负 我正在使用 python 2.6、MacOSX 10.6、NumPy 1.5.0 有什么想法吗?

4

2 回答 2

1

从 Numpy 1.5 开始?

“Time for Action - 添加向量”中的介绍性示例将仅在允许长整数的 64 位平台上运行。否则会返回错误的结果:

The last 2 elements of the sum [-2143491644 -2143487647]

为了解决这个问题,将幂函数中的整数转换为浮点数,以便转发浮点值。结果:加速了 10 倍

$ python vectorsum.py 1000000

和的最后 2 个元素 [9.99995000008e+17, 9.99998000001e+17]

PythonSum 以微秒为单位的经过时间 3 59013

和的最后 2 个元素 [ 9.99993999e+17 9.99996999e+17]

NumPySum 以微秒为单位的经过时间 0 308598

更正后的例子:

导入系统

从日期时间导入日期时间

导入 numpy

def numpysum(n):

a = numpy.arange(n) ** 2.

b = numpy.arange(n) ** 3.

c = a + b

return c

def pythonsum(n): a = range(n)

  b = range(n)

  c = []

  for i in range(len(a)):

      a[i] = i ** 2.     # notice the dot (!)

      b[i] = i ** 3.

      c.append(a[i] + b[i])

  return c

大小 = int(sys.argv[1])

开始 = datetime.now()

c = pythonsum(大小)

delta = datetime.now() - 开始

print "和的最后两个元素", c[-2:]

打印“PythonSum 以微秒为单位的经过时间”,delta.seconds,delta.microseconds

开始 = datetime.now()

c = numpysum(大小)

delta = datetime.now() - 开始

print "和的最后两个元素", c[-2:]

打印“NumPySum 以微秒为单位的经过时间”,delta.seconds,delta.microseconds

该代码在此处的 pastebin 中可用http://paste.ubuntu.com/1169976/

于 2012-08-27T09:12:22.543 回答
0

我认为这个线程有一些混乱。纯 Python,即非numpy,代码工作的原因与 32 位和 64 位没有任何关系。它可以在以下任何一个上正常工作: Pythonint可以是任意大小。[在后台有一些实现细节,涉及它是否调用某物int或 along但您不必担心,转换是无缝的。这就是为什么有时你会看到L一个数字的末尾。]

例如:

>>> 2**100
1267650600228229401496703205376L

另一方面,numpy整数dtypes是固定精度的,并且对于足够大的数字总是会失败,无论有多宽:

>>> for kind in numpy.int8, numpy.int16, numpy.int32, numpy.int64:
...     for power in 1, 2, 5, 20:
...         print kind, power, kind(10), kind(10)**power
... 
<type 'numpy.int8'> 1 10 10
<type 'numpy.int8'> 2 10 100
<type 'numpy.int8'> 5 10 100000
<type 'numpy.int8'> 20 10 -2147483648
<type 'numpy.int16'> 1 10 10
<type 'numpy.int16'> 2 10 100
<type 'numpy.int16'> 5 10 100000
<type 'numpy.int16'> 20 10 -2147483648
<type 'numpy.int32'> 1 10 10
<type 'numpy.int32'> 2 10 100
<type 'numpy.int32'> 5 10 100000
<type 'numpy.int32'> 20 10 1661992960
<type 'numpy.int64'> 1 10 10
<type 'numpy.int64'> 2 10 100
<type 'numpy.int64'> 5 10 100000
<type 'numpy.int64'> 20 10 7766279631452241920

您可以numpy通过告诉纯 Python 使用 Python 类型 ie 来获得与纯 Python相同的结果dtype=object,尽管性能会受到显着影响:

>>> import numpy
>>> numpy.array([10])
array([10])
>>> numpy.array([10])**100
__main__:1: RuntimeWarning: invalid value encountered in power
array([-2147483648])
>>> numpy.array([10], dtype=object)
array([10], dtype=object)
>>> numpy.array([10], dtype=object)**100
array([ 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000], dtype=object)
于 2012-08-27T15:25:42.047 回答