3

このコードを高速化する簡単な方法が必要だと思います。答えはここにあると思いますが、その形式で問題を解決できないようです。私が解決しようとしている根本的な問題は、平行成分と垂直成分に関して点ごとの違いを見つけ、これらの違いの 2D ヒストグラムを作成することです。

out = np.zeros((len(rpbins)-1,len(pibins)-1))
tmp = np.zeros((len(x),2))
for i in xrange(len(x)):
    tmp[:,0] = x - x[i]
    tmp[:,1] = y - y[i]

    para = np.sum(tmp**2,axis=-1)**(1./2)
    perp = np.abs(z - z[i])

    H, _, _ = np.histogram2d(para, perp, bins=[rpbins, pibins])
    out += H
4

1 に答える 1

3

このようなものをベクトル化するのは注意が必要です。なぜなら、要素のループを取り除くにはnの配列を作成する(n, n)必要があるためです。そのため、大きな入力の場合、Python ループよりもパフォーマンスが低下する可能性があります。しかし、それは行うことができます:

mask = np.triu_indices(x.shape[0], 1)
para = np.sqrt((x[:, None] - x)**2 + (y[:, None] - y)**2)
perp = np.abs(z[:, None] - z)
hist, _, _ = np.histogram2d(para[mask], perp[mask], bins=[rpbins, pibins])

これmaskは、各距離を 2 回カウントしないようにするためです。また、対角オフセットを に設定して、各ポイントからそれ自体までの距離がヒストグラムに1含まれないようにしました。ただし、インデックスを0作成しないと、コードとまったく同じ結果が得られます。paraperp

このサンプル データを使用すると、次のようになります。

items = 100
rpbins, pibins = np.linspace(0, 1, 3), np.linspace(0, 1, 3)
x = np.random.rand(items)
y = np.random.rand(items)
z = np.random.rand(items)

histとあなたのためにこれを取得しますout

>>> hist
array([[ 1795.,   651.],
       [ 1632.,   740.]])
>>> out
array([[ 3690.,  1302.],
       [ 3264.,  1480.]])

out[i, j] = 2 * hist[i, j]除いてi = j = 0、各アイテムからそれ自体までout[0, 0] = 2 * hist[0, 0] + itemsの距離が原因です。0


EDIT tcaswellのコメントの後に次のことを試しました:

items = 1000
rpbins, pibins = np.linspace(0, 1, 3), np.linspace(0, 1, 3)
x, y, z = np.random.rand(3, items)

def hist1(x, y, z, rpbins, pibins) :
    mask = np.triu_indices(x.shape[0], 1)
    para = np.sqrt((x[:, None] - x)**2 + (y[:, None] - y)**2)
    perp = np.abs(z[:, None] - z)
    hist, _, _ = np.histogram2d(para[mask], perp[mask], bins=[rpbins, pibins])
    return hist

def hist2(x, y, z, rpbins, pibins) :
    mask = np.triu_indices(x.shape[0], 1)
    para = np.sqrt((x[:, None] - x)[mask]**2 + (y[:, None] - y)[mask]**2)
    perp = np.abs((z[:, None] - z)[mask])
    hist, _, _ = np.histogram2d(para, perp, bins=[rpbins, pibins])
    return hist

def hist3(x, y, z, rpbins, pibins) :
    mask = np.triu_indices(x.shape[0], 1)
    para = np.sqrt(((x[:, None] - x)**2 + (y[:, None] - y)**2)[mask])
    perp = np.abs((z[:, None] - z)[mask])
    hist, _, _ = np.histogram2d(para, perp, bins=[rpbins, pibins])
    return hist

In [10]: %timeit -n1 -r10 hist1(x, y, z, rpbins, pibins)
1 loops, best of 10: 289 ms per loop

In [11]: %timeit -n1 -r10 hist2(x, y, z, rpbins, pibins)
1 loops, best of 10: 294 ms per loop

In [12]: %timeit -n1 -r10 hist3(x, y, z, rpbins, pibins)
1 loops, best of 10: 278 ms per loop

ほとんどの時間は、実際の計算ではなく、新しい配列のインスタンス化に費やされているようです。

于 2013-02-19T08:16:06.403 に答える