1

カイ二乗関数を評価しようとしています。つまり、任意の (ブラックボックス) 関数をデータの numpy ベクトル配列と比較します。現時点では、Python で配列をループしていますが、このようなものは非常に遅いです。

n=len(array)
sigma=1.0
chisq=0.0
for i in range(n):
    data = array[i]
    model = f(i,a,b,c)
    chisq += 0.5*((data-model)/sigma)**2.0
return chisq

array は 1 次元の numpy 配列で、a、b、c はスカラーです。numpy.sum() またはある種のラムダ関数などを使用してこれを高速化する方法はありますか? 次のように 1 つのループ (chisq 経由) を削除する方法を確認できます。

numpy.sum(((array-model_vec)/sigma)**2.0)

ただし、配列 model_vec を明示的に設定する必要がありますが、これはおそらく同じくらい遅くなります。次のような明示的なループなしでそれを行うにはどうすればよいですか:

model_vec=numpy.zeros(len(data))
for i in range(n):
    model_vec[i] = f(i,a,b,c)
return numpy.sum(((array-model_vec)/sigma)**2.0)

?

ありがとう!

4

2 に答える 2

1

関数の定義を制御できない場合はnp.vectorize、関数を「ベクトル化」するために使用できます。f

g = np.vectorize(f)

しかし、これは配列をサポートするために自分で関数を手動でベクトル化するほど良くはありません。実際にはループを内部化する以上のことを行うわけではなく、特定の関数ではうまく機能しない可能性があるからです。実際、ドキュメントから:

このvectorize関数は、パフォーマンスのためではなく、主に利便性のために提供されています。実装は基本的に for ループです。

f代わりに、次の代わりにベクトルを受け入れるようにすることに集中する必要がありiます。

def f(i, a, b, x):
    return a*x[i] + b

def g(a, b, x):
    x = np.asarray(x)
    return a*x + b

次に、 を呼び出す代わりに、 th のみが必要な場合は をf(i, a, b, x)呼び出しますが、関数全体の操作には、 and を使用するとはるかに高速になります。g(a,b,x)[i]ig(a, b, x)

model_vec = g(a, b, x)
return numpy.sum(((array-model_vec)/sigma)**2.0)
于 2013-04-26T15:14:51.397 に答える
0

ループで実行されているものが遅い (モデル生成) ため、コードが遅いようです。これをワンライナーに変えても、スピードは上がりません。CPU を超える最新のコンピューターにアクセスできる場合は、このループを並行して実行することを試みることができます。たとえば、multiprocessingモジュールを使用します。

from multiprocessing import Pool

if __name__ == '__main__':

    # snip set up code

    pool = Pool(processes=4)              # start 4 worker processes
    inputs = [(i,a,b,c) for i in range(n)]
    model_array = pool.map(model, inputs)

    for i in range(n):
        data = array[i]
        model = model_array[i]
        chisq += 0.5*((data-model)/sigma)**2.0
于 2013-04-26T12:20:23.827 に答える