0

Given a 2D-list of integers, how can I calculate the average of the vertical, horizontal and diagonal neighbors of each element? The results need to be printed as floating point numbers and in a matrix with every row on one line.

So an example 2D-list is:

matrix = [[3, 9, 0],
          [4, 1, 4],
          [3, 8, 5]]

and the output for this one would then be:

[4.666666666666667, 2.4, 4.666666666666667]
[4.8, 4.5, 4.6]
[4.333333333333333, 3.4, 4.333333333333333]

As further clarification. For the element in row and column 1 it would be:

(9+4+1)/3 = 4.667

  • Does this answer your question? [Determining neighbours of cell two dimensional list](https://stackoverflow.com/questions/1620940/determining-neighbours-of-cell-two-dimensional-list) – Max Feb 11 '22 at 16:13
  • @MaxMiller I understand what they are doing and it already helps a lot, I just wouldn't know how to calculate the averages from this –  Feb 11 '22 at 16:40

3 Answers3

0

Find the row and column of the value in question. Then just surround the next part in try excepts to see if there is an index error. To find surrounding neighbors, you just increment and decrement both the row and column until all permutations are covered to collect the value, and then find the average. Surround all of this in a for loop that iterates over the entire matrix and stores the value in a blank matrix outside the loop.

create empty matrix
for i in rows:
    for j in rows[i]:
        list = []
        value1 = rows[i-1][j-1]
        value2 = rows[i][j-1]
        ... to value9
        add all values to the list
        calculate the mean
        store the mean in the i,j spot in the matrix above

Be sure to include try excepts around each value statement since you can run into index errors.

bballboy8
  • 400
  • 6
  • 25
  • You make it sound so easy. I will try my best in coding this, but I am still at a loss to be honest. I mean I know theoretically what to do, only I don't know how. –  Feb 11 '22 at 15:52
  • I'll add some pseudocode above. – bballboy8 Feb 11 '22 at 18:27
  • I edited my original post to include my attempt at a solution. Alas I still have not managed to get there. –  Feb 12 '22 at 00:30
0

Okay, so to make it easy, just distinguish that there are three cases for EACH SYMETRIC matrix:

  • Element is the corner - it has 3 neighbours
  • Element is part of the edge, but not the corner - it has 5 neighbours
  • Element is neither corner or edge - it has 8 neighours

There are also 4 possible corners and 4 possible eges for all 2D matrixes.(Excluding those with 1 column, row, which I would call vectors)

Pseudocode:(We assume proper matrix with equal numbers of elements in rows and columns)

matrix = [[1,2,3],[4,5,6],[7,8,9]]
rows=len(matrix)
cols=len(matrix[0])
sumation=0
for i in range(len(matrix)):
    doesleftexist=1
    doestopexist=1
    doesbottomexist=1
    doesrightexist=1
    for j in range(len(matrix[0])):
        if(i==0): #element to the top doesn't exist
            doesleftexist=0
        if(j==0): #element to the left doesn't exist
            doestopexist=0
        if(i==rows-1) #element to the bottom doesn't exist
            doesbottomexist=0
        if(j==cols-1) #element to the right doesn't exist
            doesrightexist=0
        if(doesleftexist=0 && doesbottomexist=0): #we are at bottom left
            sumation=matrix[rows-2][0]+matrix[rows-2][1]+matrix[rows-1][1]
        ... acordingly with different corners,
        each different case is else if
        
        if(doesbottomexist=0&&(doesleftexist==1 && doesrightexist==1)) #we are at bottom "not corner"
            sumation=matrix[i][j-1]+matrix[i-1][j-1]+matrix[i-1][j]+matrix[i-1][j+1]+matrix[i][j+1]
        ... acordingly with different edges
        each different case is else if
        
        else:
            sumation = [8 elements around the matrix[i][j]]
                    

I didn't apply the list sumation, but it's easy just adding the incrementation of some dummy variable, knowing that you will go in each row by column. It's kinda long and for sure not optimal solution to the problem (17 cases in total), but for sure it will give a solution for all matrixes, which are atleast 3x3.

  • Wow, thanks! This definitely works. It is quite a doozy but I totally understand what you are doing here. Thanks, I will accept this answer until a more simple approach comes along. But I am forever in you debt! Thank you very much!! –  Feb 12 '22 at 00:52
  • I do still want to try and fix it myself though. It's frustrating when you're so close. –  Feb 12 '22 at 01:03
  • Okay, I think there is one way simplier solution that this. You basically just do the sumation in for loop for the last case - trying to sum all 8 elements around the matrix[i][j] element, however, when you will get the exception because you are out of range, you simply pass this element. Check try-except, it would work in few lines then. – Michał Mazur Feb 12 '22 at 01:15
  • I edited my original comment to add my attempts at the solution but I am just off. I added my code as well as the results I get as of this moment. It seems that the values to the left and top loop through to "the other side" of the matrix again. Sorry if that's unclear but can't explain it any better. Could you maybe take a look to see what I did wrong there? –  Feb 12 '22 at 01:19
  • I'm having simillar issue now, if I will find solution I will make another solution. – Michał Mazur Feb 12 '22 at 01:26
  • Okay, got it, check solution. – Michał Mazur Feb 12 '22 at 01:46
0

Okay, I have written the solution with try-except mechanism. The issue that can occur here is the fact, that in python it is possible to make negative indexing, so for your matrix the command matrix[-1][-1] returns 5.

Solution? Simple if clause.

matrix = [[1,2,3],[4,5,6],[7,8,9]]
rows=len(matrix)
cols=len(matrix[0])
sumation=[]
numbers=[]
for i in range(rows):
    for j in range(cols):
        print(i,j)
        val=0
        values=[]
        if (i-1>=0 and j-1>=0):
            val+=matrix[i-1][j-1]
            values.append(matrix[i-1][j-1])
        
        if (i-1>=0):
            val+=matrix[i-1][j]
            values.append(matrix[i-1][j])
     
        if (i-1>=0):
            try:
                val+=matrix[i-1][j+1]
                values.append(matrix[i-1][j+1])
            except IndexError:
                pass
    
        if (j-1>=0):
            val+=matrix[i][j-1]
            values.append(matrix[i][j-1])
        
        try:
            val+=matrix[i][j+1]
            values.append(matrix[i][j+1])
        except IndexError:
            pass
        
       
        if (j-1>=0):
            try:
                val+=matrix[i+1][j-1]
                values.append(matrix[i+1][j-1])
            except IndexError:
                pass       
        try:
            val+=matrix[i+1][j]
            values.append(matrix[i+1][j])
        except IndexError:
            pass
        
        try:
            val+=matrix[i+1][j+1]
            values.append(matrix[i+1][j+1])
        except IndexError:
            pass       
        sumation.append(val)
        numbers.append(values)
print(sumation)
print(numbers)

There is the code to sum each neighbour elements of matrix element, i guess you will manage from here.