Numpy 2d массив: учет граничных элементов при изменении соседних элементов - PullRequest
0 голосов
/ 16 февраля 2020

Я использую упражнения CodeSignal для изучения программирования, так что здесь все в порядке. У меня есть массив 2d numpy (называемый matrix ) (хотя не обязательно должен быть numpy, если для этого существует какая-либо лучшая структура), и 2 для циклов, которые через l oop каждый элемент в матрице, проверяя, соответствует ли он какому-либо условию. Я создал массив np.zeros того же размера, что и матрица ввода (называемая result ), которая будет заполнена моим результатом.

Вернуться к циклам for. Когда условие выполняется для данного элемента с индексами i, j, равными matrix , я хочу, чтобы программа идентифицировала все соседние элементы и добавила 1 к каждому из них.

Так, например, если

matrix = [[True, False, False], 
         [False, False, False], 
         [False, False, False]]

Тогда

result = [[0, 1, 0], 
          [1, 1, 0], 
          [0, 0, 0]] 

Что у меня сейчас:

matrix = np.array(matrix)            
(row, col) = matrix.shape
result = np.zeros((row,col), dtype=int)

for i in range(0, row): 
    for j in range(0, col):
        print(i,j)
        if matrix[i,j] == True:
             matrix[i-1:i+2, j-1:j+2] += 1      ##problem 
return result 

Проблема со строкой у меня указано, конечно, это не работает, если элемент находится на границе, так как нет i-1 или i + 2 et c .. (я пытался, нет сообщения об ошибке, он просто не выполняет какую-либо функцию на матрица нулей). Я мог бы написать кучу операторов if, например, если i == 0 или j == 0 или i == row или j == col, и указать отдельные срезы для каждого, но должен быть способ проще, чем тот, который я не могу думать или найти.

Заранее спасибо за помощь.

Ответы [ 2 ]

2 голосов
/ 17 февраля 2020

Добавление подматриц:

matrix = np.array(matrix)            
result = np.zeros(matrix.shape, dtype=int)
result[1:,1:] += matrix[:-1,:-1]
result[1:,:] += matrix[:-1,:]
result[1:,:-1] += matrix[:-1,1:]
result[:,1:] += matrix[:,:-1]
result[:,:-1] += matrix[:,1:]
result[:-1,1:] += matrix[1:,:-1]
result[:-1,:] += matrix[1:,:]
result[:-1,:-1] += matrix[1:,1:]
0 голосов
/ 17 февраля 2020

То, что вы хотите сделать, - это свернуть матрицу, используя ядро ​​[[1,1,1],[1,1,1],[1,1,1]], а затем заменить начальные ячейки нулями. Обычный способ - использовать scipy для этого, вот так:

>>> matrix = np.array([[True, False, False], 
                  [False, False, False], 
                  [False, False, False]])
>>> M = scipy.signal.convolve2d(matrix, 
           np.array([[1,1,1],[1,1,1],[1,1,1]]), 
           mode='same')
>>> M
array([[1, 1, 0],
   [1, 1, 0],
   [0, 0, 0]])

Однако numpy позволяет выполнять только 1D свертку. Но так как наше ядро ​​очень симметрично c, я нашел несколько хакерский способ достижения того же результата, что и при двумерной свертке:

M = np.vstack([np.convolve(n, [1, 1, 1], 'same') for n in matrix])
M = np.column_stack([np.convolve(n, [1, 1, 1], 'same') for n in matrix.T])

Если вы хотите присвоить начальные ячейки нулям, возможно сделать это так:

np.logical_xor(M, matrix)
...