Search code examples
pythonarraysbinary-search

Anybody knows how to do a binary search with a 2d array of strings?


This is my array:

import numpy as np

Arr = np.array( [
    ["","A","B","C","D","E","F"],
    ["1","0","0","0","0","0","0"],
    ["2","0","0","0","0","0","0"],
    ["3","0","X","0","0","0","0"],
    ["4","0","0","0","0","0","0"],
    ["5","0","0","0","X","0","0"],
    ["6","X","0","0","0","0","0"],
    ["7","0","0","0","0","0","0"],
    ["8","0","0","0","0","0","0"]
])

I want to do a binary search but I don't know how to do it with an array of strings. Basically I want to look at the position in where all my "X" are.

def findRow(a, n, m, k):
#a is the 2d array
#n is the number of rows
#m is the number of columns
#k is the "X"
    l = 0
    r = n - 1
    mid = 0
    while (l <= r) :
        mid = int((l + r) / 2)
         
        # we'll check the left and
        # right most elements
        # of the row here itself
        # for efficiency
        if(k == a[mid][0]): #checking leftmost element
            print("Found at (" , mid , ",", "0)", sep = "")
            return
         
        if(k == a[mid][m - 1]): # checking rightmost element
            t = m - 1
            print("Found at (" , mid , ",", t , ")", sep = "")
            return
        if(k > a[mid][0] and k < a[mid][m - 1]):    # this means the element
                                                    # must be within this row
            binarySearch(a, n, m, k, mid)    # we'll apply binary
                                            # search on this row
            return
        if (k < a[mid][0]):
            r = mid - 1
        if (k > a[mid][m - 1]):
            l = mid + 1
 
def binarySearch(a, n, m, k, x):    #x is the row number
     
    # now we simply have to apply binary search as we
    # did in a 1-D array, for the elements in row
    # number
    # x
    l = 0
    r = m - 1
    mid = 0
    while (l <= r):
        mid = int((l + r) / 2)
         
        if (a[x][mid] == k):
            print("Found at (" , x , ",", mid , ")", sep = "")
            return
        if (a[x][mid] > k):
            r = mid - 1
        if (a[x][mid] < k):
            l = mid + 1
     
    print("Element not found")

This is what I have tried but this is for int 2d arrays. Now I have a string 2d Array and I'm trying to find the location of al my "X"'s.

I want to output to be: found in (A,6), (B,3), (D,5)


Solution

  • Basically I want to look at the position in where all my "X" are.

    You can use np.where to get the indices for each axis, then zip them to get index tuples for all the locations:

    >>> list(zip(*np.where(Arr == "X")))
    [(3, 2), (5, 4), (6, 1)]
    

    If you want the (row, column) "locations", you could do this:

    >>> [(Arr[row, 0], Arr[0, col]) for row, col in zip(*np.where(Arr == "X"))]
    [('3', 'B'), ('5', 'D'), ('6', 'A')]
    

    However, you seem to be treating an array as a table. You should consider using Pandas:

    >>> df = pd.DataFrame(Arr[1:, 1:], columns=Arr[0, 1:], index=range(1, len(Arr[1:]) + 1))
    
    >>> df
       A  B  C  D  E  F
    1  0  0  0  0  0  0
    2  0  0  0  0  0  0
    3  0  X  0  0  0  0
    4  0  0  0  0  0  0
    5  0  0  0  X  0  0
    6  X  0  0  0  0  0
    7  0  0  0  0  0  0
    8  0  0  0  0  0  0
    
    >>> rows, cols = np.where(df == "X")
    
    >>> [*zip(df.index[rows], df.columns[cols])]
    [(3, 'B'), (5, 'D'), (6, 'A')]