【问题标题】:Perform mathematical operation on specific matrix elements using index vectors使用索引向量对特定矩阵元素执行数学运算
【发布时间】:2020-06-29 15:37:13
【问题描述】:

我想基于 3D 掩码(包含 1 和 0)对 3D 数据集上的特定元素执行简单的操作。我想做的操作是除法,因为我不想将 NaN 引入我的数据集,所以我只想对掩码内的元素执行除法。另外,我将在具有相当大矩阵的大型数据集上执行此操作,因此我想尽可能避免 for 循环。

这里有一些代码:

inside_mask = numpy.where(mask_data>0)

这给了我一个三个 1 x 97442 的向量,其值对应于我的掩码中的一个索引,其中我有一个“一”。即 vector1[0]、vector2[0]、vector3[0] 是我有“一个”的第一个元素。

因此我可以这样做:

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

所以问题很简单:如何仅使用元素操作而不使用 for 循环来做到这一点?

此致,杰斯帕

【问题讨论】:

    标签: python numpy matrix indexing


    【解决方案1】:

    您可以使用逻辑索引。

    例子:

    # 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】:
    import numpy as np
    
    myarr = np.random.randint(2,size=[10,10,10]).astype(float)
    someValue  = 3
    myarr[myarr>0] = myarr[myarr>0]/someValue
    

    【讨论】:

    • 非常感谢!
    【解决方案3】:

    制作一个示例二维数组:

    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]])
    

    这些元素的位置/非零索引:

    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. ]])
    

    【讨论】:

    • 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-12-10
    • 2014-06-25
    • 1970-01-01
    • 2023-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    相关资源
    最近更新 更多