加速 Numpy 掩蔽
Speeding up Numpy Masking
在考虑如何优化方面,我仍然是一个成熟的人。我有这部分代码,它接受已找到的峰的列表,并找到这些峰,+/- 某个值,位于多维数组中的位置。然后它将 +1 添加到它们的 zeros 数组的索引中。代码运行良好,但执行起来需要很长时间。例如,如果 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)
方法 #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)
在考虑如何优化方面,我仍然是一个成熟的人。我有这部分代码,它接受已找到的峰的列表,并找到这些峰,+/- 某个值,位于多维数组中的位置。然后它将 +1 添加到它们的 zeros 数组的索引中。代码运行良好,但执行起来需要很长时间。例如,如果 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)
方法 #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)