pythonarraysnumpysudoku

How to remove numbers in an array if it exists in another another


Here is my code so far. (Using NumPy for arrays)

avail_nums = np.array([1,2,3,4,5,6,7,8,9]) # initial available numbers

# print(avail_nums.shape[0])
# print(sudoku[spaces[x,1],spaces[x,2]]) # index of missing numbers in sudoku
            
print('\n')
           
# print(sudoku[spaces[x,1],:]) # rows of missing numbers
                         
for i in range(sudoku[spaces[x,1],:].shape[0]): # Number of elements in the missing number row    
                
    for j in range(avail_nums.shape[0]): # Number of available numbers
                    
        if(sudoku[spaces[x,1],i] == avail_nums[j]):
                        
            avail_nums= np.delete(avail_nums,[j])
                        
print(avail_nums)

A for loop cycles through all the elements in the 'sudoku row' and nested inside, another loop cycles through avail_nums. Every time there is a match (given by the if statement), that value is to be deleted from the avail_nums array until finally all the numbers in 'sudoku row' aren't in avail_nums.

I'm greeted with this error:

IndexError: index 8 is out of bounds for axis 0 with size 8

pointing to the line with the if statement. Because avail_nums is shrinking, after the first deletion this happens. How can I resolve this issue?


Solution

  • When you are deleting items from the array, the array is getting smaller but your for loop does not know that because it is iterating over the original size of the array. So you are getting an out of bound error. So I would avoid using the for loop and deleting from the array I am iterating over.

    My solution is to use a temporary array that contains allowed elements and then assign it to the original array name

    temporary_array=list()
    for element in array:
        If element in another_array: # you can do this in Python
            continue # ignore it
        temporary_array.append(element)
    array=temporary_array
    

    the resulting array will have only the elements that do not exist in the another_array

    You could also use list comprehension:

    temporary_array = [ element for element in array if element not in another_array ]
    array = temporary_array
    

    Which is the same concept using fancy python syntax

    Another option would be to use the builtin filter() which takes a filter function and an array and returns the filtered array. In the following I am using the lambda function notation, which is another nice Python syntax:

    array = filter(lambda x: x not in another_array, array)
    

    Since you are using numpy you should look for the numpy.extract() method here https://numpy.org/doc/stable/reference/generated/numpy.extract.html... for example using, numpy.where(), numpy.in1d() and numpy.extract() we could:

    condition = numpy.where(numpy.in1d(np_array, np_another_array),False,True)
    np_array = numpy.extract(condition, np_array)