Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set none if numpy array index does not exist

I have a function within a Python (2.7) class that should retrieve the values of the 'cells' around it in a 2 dimensional numpy array. If the index is out of range, I would the value should be set as None.

I'm struggling to find a way to do this without writing 8 try/catch statements, or without using multiple if x else None statements as is in my code below. While they would both work, they don't seem very well structured, and I'm thinking there must be a simpler way to do this - I'm probably caught thinking about this in entirely the wrong way. Any help would be much appreciated.

# This will return a dictionary with the values of the surrounding points
def get_next_values(self, column, row):
    if not (column < self.COLUMNS and row < self.ROWS):
        print "Invalid row/column."
        return False

    nextHorizIsIndex = True if column < self.COLUMNS - 2 else False
    nextVertIsIndex = True if row < self.ROWS - 2 else False

    n = self.board[column, row-1] if column > 0 else None
    ne = self.board[column+1, row-1] if nextHorizIsIndex else None
    e = self.board[column+1, row] if nextHorizIsIndex else None
    se = self.board[column+1, row+1] if nextHorizIsIndex and nextVertIsIndex else None
    s = self.board[column, row+1] if nextVertIsIndex else None
    sw = self.board[column-1, row+1] if nextVertIsIndex else None
    w = self.board[column-1, row] if row > 0 else None
    nw = self.board[column-1, row-1] if 0 not in [row, column] else None

    # debug
    print n, ne, e, se, s, sw, w, nw
like image 505
Adam Avatar asked Feb 04 '13 02:02

Adam


People also ask

How do I check if a NumPy array has NaN values?

To test array for NaN, use the numpy. isnan() method in Python Numpy. Returns True where x is NaN, false otherwise. This is a scalar if x is a scalar.

How do I check if an array is none in NP?

In numpy, we can check that whether none of the elements of given array is zero or not with the help of numpy. all() function. In this function pass an array as parameter. If any of one element of the passed array is zero then it returns False otherwise it returns True boolean value.


1 Answers

Here is a standard trick: Create your board with an edge padded with the value None. Then you can access any inner 3x3 square and fill in the appropriate values with

nw, n, ne, w, _, e, sw, s, se = (self.board[column-1:column+2, row-1:row+2]).ravel()

For example,

import numpy as np

board = np.empty((10,10), dtype = 'object')
board[:,:] = None
board[1:9, 1:9] = np.arange(64).reshape(8,8)
print(board)
# [[None None None None None None None None None None]
#  [None 0 1 2 3 4 5 6 7 None]
#  [None 8 9 10 11 12 13 14 15 None]
#  [None 16 17 18 19 20 21 22 23 None]
#  [None 24 25 26 27 28 29 30 31 None]
#  [None 32 33 34 35 36 37 38 39 None]
#  [None 40 41 42 43 44 45 46 47 None]
#  [None 48 49 50 51 52 53 54 55 None]
#  [None 56 57 58 59 60 61 62 63 None]
#  [None None None None None None None None None None]]

column = 1
row = 1
nw, n, ne, w, _, e, sw, s, se = (board[column-1:column+2, row-1:row+2]).ravel()
print(nw, n, ne, w, _, e, sw, s, se)
# (None, None, None, None, 0, 1, None, 8, 9)

Note that

  • when you define the board this way, the first non-None index is now 1, not 0.
  • I think it is more typical to think of the first index as the row, and the second index as the column, because when you print(board) that is the way the values are formatted. So perhaps you want board[row-1:row+2, column-1:column+2] instead. Of course, you could define your own print_board function, and then be free to use whatever convention you like.
like image 171
unutbu Avatar answered Oct 29 '22 17:10

unutbu