假设我们有以下数据数组:
data_array = np.array([[1, 1, 1], [1, 1, 2], [2, 2, 2], [3, 3, 3], [4, 4, 4]], np.int16)
data_array
array([[1, 1, 1],
[1, 1, 2],
[2, 2, 2],
[3, 3, 3],
[4, 4, 4]])
我们想根据以下范围对数组进行遮罩,以便能够对遮罩的部分进行计算:
intervals = [[1, 2], [2, 3], [3, 4]]
我们首先创建一个空数组和一个基于数据数组的掩码,以便我们可以将每个掩码数组的结果组合起来:
init = np.zeros((data_array.shape[0], data_array.shape[1]))
result_array = np.ma.masked_where((init == 0), init)
result_array
masked_array(
data=[[--, --, --],
[--, --, --],
[--, --, --],
[--, --, --],
[--, --, --]],
mask=[[ True, True, True],
[ True, True, True],
[ True, True, True],
[ True, True, True],
[ True, True, True]]
这样,我们可以启动一个for循环,该循环根据间隔范围对数组进行遮罩,对被遮罩的数组进行计算,然后将结果合并为单个结果数组:
for inter in intervals:
# Extact the start and en values for interval range
start_inter = inter[0]
end_inter = inter[1]
# Mask the array based on interval range
mask_init = np.ma.masked_where((data_array > end_inter), data_array)
masked_array = np.ma.masked_where((mask_init < start_inter), mask_init)
# Perform a dummy calculation on masked array
outcome = (masked_array + end_inter) * 100
# Combine the outcome arrays
result_array[result_array.mask] = outcome[result_array.mask]
具有以下结果:
array([[300.0, 300.0, 300.0],
[300.0, 300.0, 400.0],
[400.0, 400.0, 400.0],
[600.0, 600.0, 600.0],
[800.0, 800.0, 800.0]])
我的问题是,不使用此for循环如何实现相同的结果?因此,只需一次操作即可对整个data_array应用屏蔽和计算。请注意,计算变量随每个掩码而变化。是否可以将矢量化方法用于此问题?我想numpy_indexed会有所帮助。谢谢。
答案 0 :(得分:1)
如果可以使间隔不重叠,则可以使用如下函数:
import numpy as np
def func(data_array, intervals):
data_array = np.asarray(data_array)
start, end = np.asarray(intervals).T
data_array_exp = data_array[..., np.newaxis]
mask = (data_array_exp >= start) & (data_array_exp <= end)
return np.sum((data_array_exp + end) * mask * 100, axis=-1)
在这种情况下,结果应与原始代码相同:
import numpy as np
def func_orig(data_array, intervals):
init = np.zeros((data_array.shape[0], data_array.shape[1]))
result_array = np.ma.masked_where((init == 0), init)
for inter in intervals:
start_inter = inter[0]
end_inter = inter[1]
mask_init = np.ma.masked_where((data_array > end_inter), data_array)
masked_array = np.ma.masked_where((mask_init < start_inter), mask_init)
outcome = (masked_array + end_inter) * 100
result_array[result_array.mask] = outcome[result_array.mask]
return result_array.data
data_array = np.array([[1, 1, 1], [1, 1, 2], [2, 2, 2], [3, 3, 3], [4, 4, 4]], np.int16)
intervals = [[1, 1.9], [2, 2.9], [3, 4]]
print(np.allclose(func(data_array, intervals), func_orig(data_array, intervals)))
# True