Выполните математическую операцию с указанными c матричными элементами, используя индексные векторы - PullRequest
0 голосов
/ 18 марта 2020

Я хочу выполнить простую операцию с указанными c элементами в 3D-наборе данных на основе 3D-маски (содержащей единицы и нули). Операция, которую я хочу сделать, - это деление, и, поскольку я не хочу вводить данные NaN в свой набор данных, я хочу выполнять деление только для элементов внутри маски. Кроме того, я собираюсь сделать это для большого набора данных с довольно большими матрицами, поэтому я хочу избегать циклов for, пока это возможно.

Вот код:

inside_mask = numpy.where(mask_data>0)

Это дает мне три 1 на 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-l oop?

С уважением, Jesper

Ответы [ 3 ]

0 голосов
/ 18 марта 2020

Вы можете использовать логическое индексирование.

Пример:

# 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]
0 голосов
/ 18 марта 2020

Создание образца 2d массива:

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 - это целочисленный тип d, я не пытался разделить, что приведет к созданию значений с плавающей запятой.)

ufunc как у деления, добавления, и т.д. c, есть параметр 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. ]])
0 голосов
/ 18 марта 2020
import numpy as np

myarr = np.random.randint(2,size=[10,10,10]).astype(float)
someValue  = 3
myarr[myarr>0] = myarr[myarr>0]/someValue
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...