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

サイズ >= 1291 の場合、結果は負になります 私は python 2.6、MacOSX 10.6、NumPy 1.5.0 で作業しています 何かアイデアはありますか?

4

2 に答える 2

1

Numpy 1.5 の開始 ?

「アクションの時間 - ベクトルの追加」の導入例は、長整数を許可する 64 ビット プラットフォームでのみ実行されます。そうしないと、誤った結果が返されます。

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

この問題を解決するには、累乗関数の整数を float に変換して、浮動値が転送されるようにします。結果: 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

修正された例:

システムのインポート

from datetime import datetime

numpy をインポート

デフnumpysum(n):

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

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

c = a + b

return c

def pythonsum(n): a = 範囲(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(サイズ)

デルタ = datetime.now() - 開始

print "合計の最後の 2 要素", c[-2:]

print "PythonSum の経過時間 (マイクロ秒)", delta.seconds, delta.microseconds

開始 = datetime.now()

c = numpysum(サイズ)

デルタ = datetime.now() - 開始

print "合計の最後の 2 要素", c[-2:]

print "NumPySum 経過時間 (マイクロ秒)", delta.seconds, delta.microseconds

コードはこちらのペーストビンで入手できますhttp://paste.ubuntu.com/1169976/

于 2012-08-27T09:12:22.543 に答える
0

このスレッドには多少の混乱があると思います。純粋なPython、つまり非numpyコードが機能する理由は、32ビットと64ビットの違いとは関係ありません。次のいずれかで正しく機能します。Pythonintは任意のサイズにすることができます。int[バックグラウンドには、何かを呼び出すかどうかを含む実装の詳細が少しありますlongが、心配する必要はありません。変換はシームレスです。そのため、番号の最後に表示されることがあります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

numpyPythonタイプを使用するように指示することで、純粋な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 に答える