Get column of first occurence of a value in array

Question:

We have the following numpy array:

b = np.array([[0.3, -0.2, 0.4, 0.5, -0.8, 1.0, 0.0, 0.0],
             [0.6, 0.2, 0.7, 0.91, 0.67, 0.0, 1.0, 0.0],
             [0.5, 0.1, 0.7, 0.0, 0.6, 0.0, 0.0, 1.0]])

We can see here that in the right side of this array (last 3 columns) we have a diagonal matrix. How can I get the column where 1 first occur in this diagonal matrix? i.e., column 5. I tried the following, which gives the correct answer:

first_occurence = np.argmax(b == 1, axis=1)[0]

But, if we have the following array, this does not work, giving me 0 as answer (which should be 6)

b = np.array([[0.3, -0.2, 0.4, 0.5, -0.8, 0.0, 0.0, 0.0],
              [0.6, 0.2, 0.7, 0.91, 0.67, 0.0, 1.0, 0.0],
              [0.5, 0.1, 0.7, 0.0, 0.6, 0.0, 0.0, 1.0]])
Asked By: Murilo

||

Answers:

You can do this:

firsts = np.argmax(b == 1, axis=1)
first_occurence = min(firsts[firsts != 0])

The firsts[firsts != 0] argument to min() filters out rows for which b does not contain a 1, and min() then finds the column you’re looking for.

UPDATE:

Assumptions, based on OP’s clarifications:

  • the input contains a submatrix that is an identity matrix of order between 1 and b.shape[0] for input matrix b
  • the rightmost column of this identity matrix is to be found within the rightmost column of the input matrix
  • the top row of this identity matrix is between 0 and b.shape[0] - 1.

Here is a way to identify the column in the input matrix which contains the leftmost column in the embedded identity matrix:

def foo(b):
    rows = b.shape[0]
    left = b.shape[1] - rows
    for tops in range(rows):
        order = rows - tops
        eye = np.eye(order)
        for top in range(tops + 1):
            if np.allclose(b[top:top + order, left:left + order], eye):
                return left
        left += 1

Test code:

b1 = np.array([
         [0.3, -0.2, 0.4, 0.5, -0.8,  1.0, 0.0, 0.0],
         [0.6,  0.2, 0.7, 0.91, 0.67, 0.0, 1.0, 0.0],
         [0.5,  0.1, 0.7, 0.0,  0.6,  0.0, 0.0, 1.0]])
b2 = np.array([
         [0.3, -0.2, 0.4, 0.5, -0.8,  0.0, 0.0, 0.0],
         [0.6,  0.2, 0.7, 0.91, 0.67, 0.0, 1.0, 0.0],
         [0.5,  0.1, 0.7, 0.0,  0.6,  0.0, 0.0, 1.0]])
b3 = np.array([
         [0,   -0.2, 0.4, 0.5, -0.8,  1.0, 0.0, 0.0],
         [0.6, 1,    0.7, 0.91, 0.67, 0.0, 1.0, 0.0],
         [0.5, 0.1,  0.7, 0.0,  0.6,  0.0, 0.0, 1.0]])
b4 = np.array([
         [0.3, -0.2, 0.4, 0.5, -0.8,  0.0, 1.0, 0.0],
         [0.6, 0.2,  0.7, 0.91, 0.67, 0.0, 0.0, 1.0],
         [0.5, 0.1,  0.7, 0.0,  0.6,  0.0, 0.0, 1.0]])

print( foo(b1) )
print( foo(b2) )
print( foo(b3) )
print( foo(b4) )

Output:

5
6
5
6
Answered By: constantstranger
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.