web-dev-qa-db-ja.com

NumPy配列のすべてのセルでの関数の効率的な評価

NumPy 配列Aが与えられた場合、same関数、f、toeverycell?

  1. A(i、j)f(A(i、j))を割り当てるとします。

  2. 関数fにはバイナリ出力がないため、mask(ing)操作は役に立ちません。

「明らかな」二重ループの反復(すべてのセルを介した)が最適なソリューションですか?

121
Peter

vectorize 関数を使用して、必要なたびにNumpy配列に直接適用できます。

import numpy as np

def f(x):
    return x * x + 3 * x - 2 if x > 0 else x * 5 + 8

f = np.vectorize(f)  # or use a different name if you want to keep the original f

result_array = f(A)  # if A is your Numpy array

ベクトル化するときは、明示的な出力タイプを直接指定する方がおそらく良いでしょう:

f = np.vectorize(f, otypes=[np.float])
161
blubberdiblub

同様の質問は: NumPy配列を所定の位置にマッピングする です。 f()に func が見つかった場合は、outパラメーターを使用する必要があります。

5
cyborg

数値とf(A(i,j)) = f(A(j,i))を使用している場合は、 scipy.spatial.distance.cdist を使用して、A(i)A(j)の間の距離としてfを定義できます。

1

より良い解決策を見つけたと思います。関数をpythonユニバーサル関数( documentation を参照)に変更するという考え方は、内部で並列計算を実行できます。

独自のカスタマイズされたufuncをCで記述できます。これは確かに効率的であるか、組み込みのファクトリメソッドであるnp.frompyfuncを呼び出すことで実現できます。テスト後、これはnp.vectorizeよりも効率的です。

f = lambda x, y: x * y
f_arr = np.frompyfunc(f, 2, 1)
vf = np.vectorize(f)
arr = np.linspace(0, 1, 10000)

%timeit f_arr(arr, arr) # 307ms
%timeit f_arr(arr, arr) # 450ms

大きなサンプルもテストしましたが、改善は比例しています。他の方法のパフォーマンスの比較については、 this post を参照してください

0
Wunderbar