我想对基于3D遮罩(包含1和0)的3D数据集上的特定元素执行简单的操作。我要执行的操作是除法,由于我不想在数据集中引入NaN,所以我只想对蒙版内部的元素进行除法。另外,我将在具有很大矩阵的大数据集上执行此操作,因此我想尽可能避免使用for循环。
这是一些代码:
inside_mask = numpy.where(mask_data>0)
这给了我三个3乘97442的矢量,这些矢量的值对应于我的蒙版中有“ 1”的索引。即vector1 [0],vector2 [0],vector3 [0]是第一个具有“ one”元素的元素。
因此,我可以这样做:
for i in range(0,97442):
row = inside_mask[0][i]
col = inside_mask[1][i]
depth = inside_mask[2][i]
someValue = valueMatrix[row, col, depth]
calculation[row, col, depth] = signal_data[row, col, depth]/someValue
所以问题很简单:我该如何仅使用elemntwise操作而不使用for循环?
真心,杰斯珀
答案 0 :(得分:0)
import numpy as np
myarr = np.random.randint(2,size=[10,10,10]).astype(float)
someValue = 3
myarr[myarr>0] = myarr[myarr>0]/someValue
答案 1 :(得分:0)
您可以使用逻辑索引。
示例:
# Build input:
signal_data = np.ones((3, 3, 3))*2
valueMatrix = signal_data.copy()
valueMatrix[0, 0, 0] = 0
valueMatrix[0, 0, 1] = 0
valueMatrix[0, 1, 0] = 0
valueMatrix[1, 0, 0] = 0
mask_data = valueMatrix
# Calculation:
above_zero = mask_data > 0
calculation = signal_data.copy()
calculation[above_zero] = signal_data[above_zero] / valueMatrix[above_zero]
答案 2 :(得分:0)
制作示例二维数组:
In [51]: data = np.random.randint(0,3,(3,4))
In [52]: data
Out[52]:
array([[2, 0, 1, 2],
[1, 1, 0, 2],
[1, 1, 1, 2]])
非零元素的布尔掩码:
In [53]: data>0
Out[53]:
array([[ True, False, True, True],
[ True, True, False, True],
[ True, True, True, True]])
这些元素的where / nonzero索引:
In [54]: idx = np.nonzero(data>0)
In [55]: idx
Out[55]: (array([0, 0, 0, 1, 1, 1, 2, 2, 2, 2]), array([0, 2, 3, 0, 1, 3, 0, 1, 2, 3]))
该元组可以直接用于索引data
(或相同形状的任何数组):
In [56]: data[idx]
Out[56]: array([2, 1, 2, 1, 1, 2, 1, 1, 1, 2])
这与直接使用布尔掩码相同:
In [57]: data[data>0]
Out[57]: array([2, 1, 2, 1, 1, 2, 1, 1, 1, 2])
可以选择和/或修改那些非零元素
In [58]: data[idx] = data[idx] * 2
In [59]: data
Out[59]:
array([[4, 0, 2, 4],
[2, 2, 0, 4],
[2, 2, 2, 4]])
(由于data
是整数dtype,因此我没有尝试除法,这会创建浮点值。)
ufunc
(例如除法,加法等)具有where
参数。例如,取非零元素的逆:
In [71]: data = np.random.randint(0,3,(3,4)).astype(float)
In [72]: data
Out[72]:
array([[1., 0., 0., 2.],
[1., 0., 1., 2.],
[0., 2., 2., 1.]])
In [73]: np.divide(1, data, where=data>0, out=data)
Out[73]:
array([[1. , 0. , 0. , 0.5],
[1. , 0. , 1. , 0.5],
[0. , 0.5, 0.5, 1. ]])