1

このコードを Python で高速に実行しようとしていますが、MATLAB で実行される速度に近い場所で実行するのに問題があります。問題は、「SRpixels」の数が約 25000 に等しい場合、実行に約 2 秒かかる for ループのようです。

これをさらに削減する方法が見つからないようで、提案を探しています。

以下の numpy 配列のデータ型は、uint32 である **_Location[] を除いてすべて float32 です。

for j in range (0,SRpixels):
    #Skip data if outside valid range
    if (abs(SR_pointCloud[j,0]) > SR_xMax or SR_pointCloud[j,2] > SR_zMax or SR_pointCloud[j,2] < 0):
        pass
    else:           
        RIGrid1_Location[j,0] = np.floor(((SR_pointCloud[j,0] + xPosition + 5) - xGrid1Center) / gridSize)
        RIGrid1_Location[j,1] = np.floor(((SR_pointCloud[j,2] + yPosition) - yGrid1LowerBound) / gridSize)

        RIGrid1_Count[RIGrid1_Location[j,0],RIGrid1_Location[j,1]] += 1
        RIGrid1_Sum[RIGrid1_Location[j,0],RIGrid1_Location[j,1]] += SR_pointCloud[j,1]
        RIGrid1_SumofSquares[RIGrid1_Location[j,0],RIGrid1_Location[j,1]] += SR_pointCloud[j,1] * SR_pointCloud[j,1]

        RIGrid2_Location[j,0] = np.floor(((SR_pointCloud[j,0] + xPosition + 5) - xGrid2Center) / gridSize)
        RIGrid2_Location[j,1] = np.floor(((SR_pointCloud[j,2] + yPosition) - yGrid2LowerBound) / gridSize)

        RIGrid2_Count[RIGrid2_Location[j,0],RIGrid2_Location[j,1]] += 1 
        RIGrid2_Sum[RIGrid2_Location[j,0],RIGrid2_Location[j,1]] += SR_pointCloud[j,1]
        RIGrid2_SumofSquares[RIGrid2_Location[j,0],RIGrid2_Location[j,1]] += SR_pointCloud[j,1] * SR_pointCloud[j,1]

私は Cython を使用しようとしましたが、j を a に置き換えてcdef int jコンパイルしました。目立ったパフォーマンスの向上はありませんでした。誰にも提案がありますか?

4

2 に答える 2

5

ベクトル化はほとんどの場合、numpy コードを高速化する最良の方法であり、その多くはベクトル化可能のようです。たとえば、位置配列は非常に簡単に実行できます。

# these are all of your j values
inds = np.arange(0,SRpixels)

# these are the j values you don't want to skip
sel = np.invert((abs(SR_pointCloud[inds,0]) > SR_xMax) | (SR_pointCloud[inds,2] > SR_zMax) | (SR_pointCloud[inds,2] < 0))

RIGrid1_Location[sel,0] = np.floor(((SR_pointCloud[sel,0] + xPosition + 5) - xGrid1Center) / gridSize)
RIGrid1_Location[sel,1] = np.floor(((SR_pointCloud[sel,2] + yPosition) - yGrid1LowerBound) / gridSize)
RIGrid2_Location[sel,0] = np.floor(((SR_pointCloud[sel,0] + xPosition + 5) - xGrid2Center) / gridSize)
RIGrid2_Location[sel,1] = np.floor(((SR_pointCloud[sel,2] + yPosition) - yGrid2LowerBound) / gridSize)

これには python ループはありません。

残りはよりトリッキーで、何をしているかによって異なりますが、このように考えれば、ベクトル化できるはずです。

ベクトル化できず、ループで実行する必要があることが本当にある場合(これは数回しか発生していません)、Cython よりも Weave をお勧めします。使いにくいですが、C に匹敵する速度が得られるはずです。

于 2013-06-07T21:13:04.377 に答える
1

最初に計算をベクトル化してみてください。要素ごとに計算を行う必要がある場合は、スピードアップのヒントを次に示します。

  1. NumPy スカラーを使用した計算は、組み込みのスカラーよりもはるかに遅くなります。array[i, j] は numpy スカラーを取得し、array.item(i,j) は組み込みスカラーを返します。

  2. スカラー計算を行う場合、数学モジュールの関数は numpy よりも高速です。

次に例を示します。

import numpy as np
import math
a = np.array([[1.1, 2.2, 3.3],[4.4, 5.5, 6.6]])
%timeit np.floor(a[0,0]*2)
%timeit math.floor(a[0,0]*2)
%timeit np.floor(a.item(0,0)*2)
%timeit math.floor(a.item(0,0)*2)

出力:

100000 loops, best of 3: 10.2 µs per loop
100000 loops, best of 3: 3.49 µs per loop
100000 loops, best of 3: 6.49 µs per loop
1000000 loops, best of 3: 851 ns per loop

したがって、 に変更np.floormath.floor、 に変更SR_pointCloud[j,0]するSR_pointCloud.item(j,0)と、ループが大幅に高速化されます。

于 2013-06-07T23:08:32.880 に答える