2

itertools 関数 が C で書かれていることは私の理解です。このサンプル コードをスピードアップしたい場合:

import numpy as np
from itertools import combinations_with_replacement

def combinatorics(LargeArray):
     newArray = np.empty((LargeArray.shape[0],LargeArray.shape[0]))
     for x, y in combinations_with_replacement(xrange(LargeArray.shape[0]), r=2):
         z = LargeArray[x] + LargeArray[y]
         newArray[x, y] = z
     return newArray

Cで書かれているのでcombinations_with_replacement、高速化できないということですか?お知らせ下さい。

前もって感謝します。

4

1 に答える 1

4

が C で記述されているのは事実combinations_with_replacementです。つまり、コードのその部分の実装を高速化する可能性は低いということです。しかし、ほとんどのコードは組み合わせを見つけることに費やされませんfor。追加を行うのはループ上です。numpy を使用している場合は、可能な限りそのようなループを避けたいと本当に本当に本当に本当に思っています。このバージョンは、ブロードキャストの魔法によって、ほぼ同じことを行います。

def sums(large_array):
    return large_array.reshape((-1, 1)) + large_array.reshape((1, -1))

例えば:

>>> ary = np.arange(5).astype(float)
>>> np.triu(combinatorics(ary))
array([[ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  2.,  3.,  4.,  5.],
       [ 0.,  0.,  4.,  5.,  6.],
       [ 0.,  0.,  0.,  6.,  7.],
       [ 0.,  0.,  0.,  0.,  8.]])
>>> np.triu(sums(ary))
array([[ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  2.,  3.,  4.,  5.],
       [ 0.,  0.,  4.,  5.,  6.],
       [ 0.,  0.,  0.,  6.,  7.],
       [ 0.,  0.,  0.,  0.,  8.]])

違いはcombinatorics、下の三角形をランダムな意味不明のままにしsumsて、マトリックスを対称にすることです。すべてを 2 回追加することを本当に回避したい場合は、おそらく可能ですが、頭のてっぺんからそれを行う方法を思いつきません。

ああ、そして他の違い:

>>> big_ary = np.random.random(1000)
>>> %timeit combinatorics(big_ary)
1 loops, best of 3: 482 ms per loop
>>> %timeit sums(big_ary)
1000 loops, best of 3: 1.7 ms per loop
于 2013-01-23T04:28:33.487 に答える