Python Forum
Numpy array delete cells
Thread Rating:
  • 1 Vote(s) - 2 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Numpy array delete cells
#1
Hi!
I could really use some help with the following assignment I received.
Basically I created a profile in a 2D array, with active (1) and inactive (0) cells. But I have some 'disconnected' cells in my array, where basically a cell with a value of 1, is surrounded by cells with a value of 0. I would like to delete those cells, by turning their value into 1. I have written therefore the following function down below:

def find_lonely_cells(ibound_array):

    col_n = ibound_array.shape[-1] #results in 150 columns, but displays 149
    row_n = ibound_array.shape[0] #results in 120 rows (layers), but displays 119

    #   go through the ibound_arr cell by cell
    for i in xrange(col_n):
        for j in xrange(row_n):
            cell_up = ibound_array[i,0,j-1]
            cell_down = ibound_array[i,0,j+1]
            cell_right = ibound_array[i+1,0,j]
            cell_left = ibound_array[i-1,0,j]
            
            if i == 0:
                if j == 0:
                    if (cell_right == 0 and cell_down == 0):
                        ibound_array [i,0,j] == 0
                if (row_n -1) < j > 0:
                    if (cell_up == 0 and cell_right == 0 and cell_down == 0):
                        ibound_array[i,0,j] == 0
                
            elif i == (col_n - 1):
                if j == 0:
                    if (cell_left == 0 and cell_down == 0):
                        ibound_array [i,0,j] == 0
                if (row_n - 1) > j > 0:
                    if (cell_up == 0 and cell_left == 0 and cell_down == 0):
                        ibound_array[i,0,j] == 0
            
            elif j == 0:
                if i == 0:
                    if (cell_right == 0 and cell_down == 0):
                        ibound_array [i,0,j] == 0
                if (col_n -1) < i > 0:
                    if (cell_left == 0 and cell_right == 0 and cell_down == 0):
                        ibound_array[i,0,j] == 0
            
            elif j == (row_n - 1):
                if i == 0:
                    if (cell_up == 0 and cell_right == 0):
                        ibound_array [i,0,j] == 0
                if (col_n - 1) > i > 0:
                    if (cell_up == 0 and cell_left == 0 and cell_right == 0):
                        ibound_array[i,0,j] == 0
            else:
                if (col_n - 1) > i > 0 and (row_n-1) > j > 0:
                    if (cell_up == 0 and cell_right == 0 and cell_down == 0 and cell_left == 0):
                        ibound_array[i,0,j] == 0
            return ibound_array
So the ibound_array that I have is 2D, therefore I have the value 0 for [i,0,j], which stands for 0 rows.
I hope someone can advice me on the mistakes I might have in the script, and how to improve it..? I was only allowed to use if-statements here, so that's why I used this method.

Thank you!
Reply
#2
Hi :)
if you can access your array with ibound_array[i,0,j] you have a three dimensional array, though the middle value only holds one value (in this case an array). When you build your array two dimensional you should be able to access it with ibound_array[i,j] and still can store a value in it. Or is the middle dimension of importance? if so, then ignore this part ;) :D


You have to be careful with the shape. Let's say you have an array like
arr = np.array([[1,2,3],[4,5,6]])
then your shape will be (2,3) which means that the rows are represented by the first dimension an the columns by the second dimension (like you did). BUT currently your for loops are generating column indices as i and row indices as j. Currently you are using i for the rows and j for the columns. Just switch them up. finally you can make the script more easy. There are two options.
1. make your array bigger by inserting a 0 padding around the boarders. for example
arr = np.array([[1,2,3],[4,5,6]])
would now be
arr = np.array([[0,0,0,0,0],[0,1,2,3,0],[0,4,5,6,0],[0,0,0,0,0]])
Now you just need to let your indices ignore the boarders and cell_up, cell_down, etc. will have valid values. Your code would look like this:
def find_lonely_cells(ibound_array):
 
    col_n = ibound_array.shape[-1] #results in 150 columns, but displays 149
    row_n = ibound_array.shape[0] #results in 120 rows (layers), but displays 119
 
    #   go through the ibound_arr cell by cell
    for i in xrange(1, row_n - 1):
        for j in xrange(1, col_n - 1):
            cell_up = ibound_array[i,j-1]
            cell_down = ibound_array[i,j+1]
            cell_right = ibound_array[i+1,j]
            cell_left = ibound_array[i-1,j]
             
            if (cell_up == 0 and cell_right == 0 and cell_down == 0 and cell_left == 0):
                        ibound_array[i,j] == 0
     return ibound_array
2. You could reduce the if cases by doing this:
def find_lonely_cells(ibound_array):
 
    col_n = ibound_array.shape[-1] #results in 150 columns, but displays 149
    row_n = ibound_array.shape[0] #results in 120 rows (layers), but displays 119
 
    #   go through the ibound_arr cell by cell
    for i in xrange(row_n):
        for j in xrange(col_n):
            cell_up = if j == 0 then 0 else ibound_array[i,j-1]
            cell_down = if j == col_n - 1 then 0 else ibound_array[i,j+1]
            cell_right = if i == row_n -1 then 0 else ibound_array[i+1,j]
            cell_left = if i == 0 then 0 else ibound_array[i-1,j]
             
            if (cell_up == 0 and cell_right == 0 and cell_down == 0 and cell_left == 0):
                        ibound_array[i,j] == 0
     return ibound_array
I personally would prefer the first method.
(with both methods you would still just use if methods ;) )

One major problem I see is that you have the return part in your loop section so after the first iteration the loop will stop
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  creating functions which modify numpy array GSGSGKGK 0 1,580 Dec-15-2019, 07:04 PM
Last Post: GSGSGKGK
  User input numpy array with color mapping & mouse click events imakeathepi 0 3,315 Aug-15-2017, 10:33 AM
Last Post: imakeathepi
  reshaping numpy array ValueError: total size of new array must be unchanged metalray 0 5,893 Jul-15-2017, 05:41 PM
Last Post: metalray

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020