1

ローカル クラスターで順位相関計算を行うスクリプトを作成しました。X計算には、長さ 5000 ~ 10000 の2 つの配列を調べてY、数量を抽出することが含まれます。

all((X[i], Y[i]))
all((X[i], not Y[i]))
all((not X[i], Y[i]))

何千回も計算します(シャッフルするためX/Y他のものの中で)。

私たちのクラスターの 1 つは python2.4 を実行していたので、alls をnumpy.alls に変更しました。しかし、私が 5 ~ 6 時間かかると見積もった計算は、24 時間以上のマークに達していました。これにより、私は調査するようになりました。

サンプルコードは次のとおりです。

In [2]: import timeit
In [3]: s = """import numpy as np
   ...: x, y = np.random.rand(1000), np.random.rand(1000)
   ...: [all((x[i], y[i])) for i in range(1000)]
   ...: """
In [4]: timeit.timeit(s, number=1000)
Out[4]: 0.39837288856506348

In [5]: s_numpy = """import numpy as np
   ...: x, y = np.random.rand(1000), np.random.rand(1000)
   ...: [np.all((x[i], y[i])) for i in range(1000)]
   ...: """
In [9]: timeit.timeit(s_numpy, number=1000)
Out[9]: 14.641073942184448

numpy.allこれを計算するのに 50 倍の時間がかかる理由は何ですか? numpy.arrayオーバーヘッドですか?

編集:私の元の配列はnumpy.array、ここにあるような s ではありません ( np.random.rand)。行を変更する必要があるまで、私は numpy をまったく使用していませんでしたall。ただし、ループを次のようなものに置き換えました

np.sum(np.logical_and(X, Y))
np.sum(np.logical_and(X, np.logical_not(Y)))
np.sum(np.logical_and(np.logical_not(X), Y))

これにより、初期オーバーヘッドの実行と、これらのループの約 3000 の計算が 60% 程度高速化されます。ありがとう!numpy を使用して最適化する方法をさらに探します。

4

2 に答える 2

5
[np.all((x[i], y[i])) for i in range(1000)]

として書き換えることができます

x = []
for i in range(1000):
    x.append(numpy.all((x[i],y[i])))

したがって、非常に小さなリストで numpy.all を呼び出しています

numpy メソッドは通常、はるかに大きなリストで機能します

timeit.timeit('all(x)','x = numpy.arange(1,100000)',number=1)
#~.0175
timeit.timeit('numpy.all(x)','x = numpy.arange(1,100000)',number=1)
#~.00043
于 2013-08-08T18:45:40.933 に答える
0

リスト内包表記の代わりにジェネレーター内包表記を使用すると、これらの関数の両方をより高速に、より比較しやすくすることができます。

s = """
import numpy as np; 
x, y = np.random.rand(1000),np.random.rand(1000);     
(all((x[i], y[i])) for i in range(1000)) """

timeit.timeit(s,number=1000)
0.05593514442443848

s_yours = """
import numpy as np; 
x, y = np.random.rand(1000),  np.random.rand(1000);
[all((x[i], y[i])) for i in range(1000)] """

timeit.timeit(s_yours,number=1000)
0.3829691410064697


s_numpy = """import numpy as np; 
x, y = np.random.rand(1000), np.random.rand(1000); 
(np.all((x[i], y[i])) for i in range(1000))"""

timeit.timeit(s_numpy,number=1000)
0.06155896186828613

s_your_numpy = """import numpy as np; 
x, y = np.random.rand(1000), np.random.rand(1000); 
[np.all((x[i], y[i])) for i in range(1000)]"""

timeit.timeit(s_your_numpy,number=1000)
12.162676811218262

Numpy はまだ遅いかもしれませんが、男が言ったように、より大きなリストでうまく機能します。

また、なぜか

x.all(), y.all() 

オプションではありませんか?

于 2013-08-08T18:55:27.540 に答える