2016-10-13 40 views
2

当谈到如何优化时,我仍然是一个稚嫩。我有这段代码,它包含找到的峰值列表,并找出这些峰值(+/- 一些值)位于多维数组中的位置。然后它将+1加到零数组的索引中。代码运行良好,但执行需要很长时间。例如,如果ind具有270个值,并且refVals具有(3050,3130,80)的形状,则其运行接近45分钟。我知道它有很多数据可以通过,但是有没有更有效的方法来解决这个问题?加速Numpy Masking

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布尔数组,这可能比被掩码的数组更有效。此外,我们还会执行一个更高层次的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