Поддерживать 2D-структуру после логической индексации массива numpy

#python #numpy

#python #numpy

Вопрос:

Я отслеживаю динамически изменяющуюся маску, которая выполняется с использованием некоторого сдвига ввода. В этой маске хранятся значения, которые определяют, где я могу доверять значениям в другом массиве той же формы. Ниже приведен пример того, как маска изменяется на каждой итерации. У меня есть большой стек логических проверок, которые определяют, как установить свернутые части маски равными нулю, в зависимости от того, равны ли значения x и y сдвига 0 или являются положительными или отрицательными. Здесь я просто жестко запрограммировал все это для ясности.

 import numpy as np
mask = np.full((8,8), 10)

#Iteration 1
mask = np.roll(mask, (0, 1), axis = (0,1))
mask[:, :1] = 0
#logical indexing happens here
mask  = 1
print (mask)

#Iteration 2
mask = np.roll(mask, (1, 0), axis = (0,1))
mask[:1, :] = 0
#logical indexing happens here
mask  =1
print (mask)

#Iteration 3
mask = np.roll(mask, (2, -1), axis = (0,1))
mask[:, -1:] = 0
mask[:2, :] = 0
#logical indexing happens here
mask  =1
print (mask)
  

После каждой итерации и до увеличения маски на единицу мне нужно индексировать и извлекать значения второго массива, где маска превышает некоторый порог (в данном случае 10). Поскольку я переключаю и устанавливаю значения, я всегда знаю, что часть маски, которая удовлетворяет этому условию, может быть передана в 2d-массив. Упрощенный пример того, что я делаю сейчас, приведен ниже, где arr2 — это сплющенный массив.

 import numpy as np

arr1 = np.arange(0, 64, 1).reshape((8,8))
mask = np.full((8,8), 10)
mask[:, 0] = 0

arr2 = arr1[mask >= 10]
  

Как я могу сохранить arr2 в виде 2d-массива, где маска превышает установленный порог?

Я не знаю априори, каким будет сдвиг, который будет применен к маске, поэтому мне приходится полагаться на значения в маске, чтобы определить форму результирующего массива. Мои массивы намного больше, чем в этом примере, а сдвиги составляют от -5 до 5, поэтому я знаю, что не смогу приблизиться к установке всего массива ниже порогового значения. Идея заключается в том, что после ~ 10 итераций некоторые части массива снова становятся надежными и могут быть полезной информацией после логического индекса.

Комментарии:

1. применение 2D-маски к 2D-массиву всегда будет транслироваться в плоский массив, если вы вручную не установите для этого значение. Это (среди прочего) связано с тем, что количество Trues (следовательно, количество результирующих элементов) в строках или столбцах может отличаться. Исходя из ваших данных, может показаться, что вместо этого вы можете применить одномерную маску (если маска одинакова по строкам или столбцам).

2. Можете ли вы подробнее рассказать о том, как «вручную установить это не так»? Если вы имеете в виду изменение формы массива после факта, я не могу знать, какую форму имеет часть маски, которая находится выше порога, кроме того, чтобы сказать, что она соответствует тому, чтобы быть 2d-массивом.

3. изменение формы, как правило, является самым простым способом. Вы также можете использовать np.ma.MaskedArray . Однако, по крайней мере, в опубликованном вами коде, не имеет смысла использовать 2D-маску.

Ответ №1:

Ответ здесь — это обходной путь, и теперь он был очевиден, когда он некоторое время кипел в моем сознании. В принципе, поскольку я знаю, что результирующая область будет квадратной, я могу просто посчитать по строке и столбцу, где каждый индекс соответствует моему условию. Итак, продолжая мой предыдущий пример, я просто добавляю пару строк, чтобы определить, сколько значений в строке и столбце соответствуют моему условию.

 import numpy as np
#Initializing array
arr1 = np.arange(0, 64, 1).reshape((8,8))
#mask array
mask = np.full((8,8), 10)

#Setting some rows and cols to zero to simulate my roll functionality
mask[:, 0] = 0
mask[:2, :] = 0

#Summing across a row and col where condition is met
sizex = np.sum(mask[4, :] >= 10)
sizey = np.sum(mask[:, 4] >= 10)

#Using the mask to index into the original array and reshaping
arr2 = arr1[mask >= 10].reshape((sizey, sizex))