2016-10-13 1 views
2

最適化の方法について考えてみると、まだ魅力的です。私は発見されたピークのリストを取り、これらのピークがどこかの値が多次元配列にあるところを見つけるこのコードセクションを持っています。次に、ゼロ配列のインデックスに+1を加えます。コードは正常に動作しますが、実行には時間がかかります。たとえば、indの値が270で、refValsの形状が(3050,3130,80)の場合、実行には45分近くかかります。私はその多くのデータが乱れていることを理解していますが、これについてもっと効率的な方法がありますか?ナンシーマスキングのスピードアップ

maskData = np.zeros_like(refVals).astype(np.int16) 

for peak in ind: 
     tmpArr = np.ma.masked_outside(refVals,x[peak]-2,x[peak]+2).astype(np.int16) 
     maskData[tmpArr.mask == False ] += 1 
     tmpArr = None 

maskData = np.sum(maskData,axis=2) 

答えて

2

アプローチ#1:メモリが許せば、ここbroadcasting使用してベクトル化されたアプローチだ -

# Craate +,-2 limits usind ind 
r = x[ind[:,None]] + [-2,2] 

# Use limits to get inside matches and sum over the iterative and last dim 
mask = (refVals >= r[:,None,None,None,0]) & (refVals <= r[:,None,None,None,1]) 
out = mask.sum(axis=(0,3)) 

アプローチ#2:前のもので、メモリが不足した場合私たちは、ループを使用してNumPyブール値配列を使用することができ、それはマスクされた配列より効率的です。また、もう1つのレベルのsum-reductionを実行すると、反復を移動するときにデータを少なくすることができます。このように、代わりの実装は次のようなものになります -

out = np.zeros(refVals.shape[:2]).astype(np.int16) 
x_ind = x[ind] 
for i in x_ind: 
    out += ((refVals >= i-2) & (refVals <= i+2)).sum(-1) 

アプローチ#3:代わりに、我々はアプローチ#2でnp.iscloseとその制限に基づく比較を置き換えることができます。したがって、ループ内の唯一のステップは、 -

out += np.isclose(refVals,i,atol=2).sum(-1) 
+0

になります。アプローチ1はすぐに私の記憶を拭きましたが、そうでなければいいでしょう。 #2と#3は素晴らしい作品です。抜本的な改善があります。ありがとう – nanoPhD

関連する問題