"Wrapping around a matrix" to get the neighbors of a cell in a 2D array in Python

Question:

Currently I am needing to grab all 8 neighbor cells of each cell in a 2D array/matrix

Now, as you may know, cells at the begginings and ends of a matrix only have either 3 or 5 neighbor cells. However, I want to register cells from the first and last rows and columns of the matrix as neighbors of the last and first rows and columnns of the matrix. In a sense, I need to "wrap around" the matrix to do this.

My code currently grabs all "available" neighbor cells. Code is:

def getNeighbours(matrix): #function to get and store nighbor cells in a new matrix called neighbourMatrix
    m , n  = len(matrix), len(matrix[0])#generate size of neighbourMatrix from size of rows and columns of original matrix
    neighbourMatrix = [['' for j in range(n)] for i in range(m)]

    def idx_gen(y, x , m, n):#generate indeces of neighbour matrix based around which cell we are viewing in the originla matrix
        v = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1),(1, -1), (1, 0), (1, 1)]
        for val in v:
            if (0 <= y + val[0] < m) and (0 <= x + val[1] < n): 
                yield y + val[0] , x + val[1]

    for i in range(m):
        for j in range(n):#looping through matrix
            for idx in idx_gen(i, j, m, n):
                neighbourMatrix[i][j] += matrix[idx[0]][idx[1]] #initialize and store neighbor values
    return neighbourMatrix#return nighbors in matrix
       
       
#call function to get neighbouring cells and store it in a matrix called "neighbourMatrix"
neighbourMatrix = getNeighbours(matrix)
print("Neighbor matrix is:: ", neighbourMatrix)

and my output is:

The starting matrix is::  [['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-'], ['-', '-', '-', '+', '-', '-', '-', '+', '-', '-', '-', '+', '-', '-', '+', '-', '-', '-', '-', '-'], ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-'], ['+', '+', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-'], ['-', '+', '-', '+', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-'], ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-'], ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '-', '+'], ['-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '-', '+'], ['+', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-'], ['-', '-', '+', '-', '-', '-', '-', '-', '-', '-', '-', '+', '-', '-', '-', '-', '-', '-', '+', '-']]

Neighbor matrix is::  [['---', '-----', '----+', '---+-', '--+--', '-----', '----+', '---+-', '--+--', '-----', '----+', '---+-', '--+--', '----+', '---+-', '--+--', '-----', '-----', '-----', '---'], ['-----', '--------', '----+---', '--------', '---+----', '--------', '----+---', '--------', '---+----', '--------', '----+---', '--------', '---+---+', '----+-+-', '-----+--', '---+----', '--------', '--------', '--------', '-----'], ['---++', '-----++-', '--+--+--', '-+------', '+-------', '--------', '--+-----', '-+------', '+-------', '--------', '--+-----', '-+------', '+---+--+', '--+---+-', '-+-+-+--', '+-------', '--------', '--------', '--------', '-----'], ['--+-+', '---+--+-', '---+-+-+', '------+-', '-----+--', '--------', '--------', '-------+', '------+-', '-----+--', '--------', '--------', '--+-+---', '-+------', '+--+---+', '------+-', '-----+--', '--------', '--------', '-----'], ['+++--', '++------', '+--++---', '--------', '---+----', '--------', '--------', '----+---', '--------', '---+----', '--------', '--------', '--+-----', '-+------', '+---+---', '--------', '---+----', '--------', '--------', '-----'], ['-+---', '-+------', '+-+-----', '-+------', '+-------', '--------', '--------', '--+-----', '-+------', '+-------', '-------+', '------+-', '-----+--', '--------', '--+-----', '-+------', '+-------', '--------', '-------+', '----+'], ['-----', '--------', '--------', '--------', '--------', '-------+', '------+-', '-----+--', '--------', '--------', '----+--+', '------+-', '---+-+--', '--------', '--------', '--------', '--------', '--------', '----+--+', '----+'], ['---+-', '-----+--', '--------', '--------', '--------', '----+---', '--------', '---+----', '--------', '--------', '--+-+---', '-+------', '+--+----', '--------', '--------', '--------', '--------', '--------', '--+-+---', '-+---'], ['-----', '---+---+', '------+-', '-----+--', '--------', '--+-----', '-+------', '+-------', '--------', '--------', '--+----+', '-+----+-', '+----+--', '--------', '--------', '--------', '--------', '-------+', '--+---+-', '-+-+-'], ['+--', '+---+', '-----', '---+-', '-----', '-----', '-----', '-----', '-----', '-----', '----+', '-----', '---+-', '-----', '-----', '-----', '-----', '----+', '-----', '--+']] 

As you can see, in my output, some cells have neighbors of only sets of 3 or 5, but I need 8.

the original string that I am analyzing is as follows:

--------------------
---+---+---+--+-----
-------------+------
++-----------+------
-+-+----+------+----
--------------------
-----------+-------+
------+----+-------+
+-------------------
--+--------+------+-
Asked By: Andrew Marra

||

Answers:

It actually takes a relatively minor modification to your code to make this work. You’re talking about a modulo operation, so that’s what we use:

def getNeighbours(matrix):
    h , w  = len(matrix), len(matrix[0])

    def idx_gen(y, x , w, h):
        v = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1),(1, -1), (1, 0), (1, 1)]
        for dx,dy in v:
            x0 = (x+dx+w)%w
            y0 = (y+dy+h)%h
            yield y0, x0

    neighbourMatrix = []
    for i in range(h):
        row = []
        for j in range(w):
            row.append( ''.join( matrix[y][x] for y,x in idx_gen(i, j, w, h)))
        neighbourMatrix.append(row)
    return neighbourMatrix
Answered By: Tim Roberts
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.