1

I have a 1d array and want to find the last value like this.

a = np.array([1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1])
# find the index that value(7) last appear.
np.argwhere(a >= 7).max()
# output 10

But it's suit for 1d array and how about 3d array.

b = np.tile(a.reshape(15,1,1), reps=(1,30,30))
# now b is 3d array and i want to use same way to the axis = 0 in 3d array.
np.argwhere(b >= 7)
# return a 2d array. It's not what i need.

Although I could use 'for' loop the other axis, but I want to solve it efficiently by numpy.

4
  • @StephenRauch Sorry, should be apply .max() Commented Mar 22, 2017 at 6:38
  • Did either of the posted solutions work for you? Commented Mar 23, 2017 at 17:17
  • @Divakar Thanks, it works. But there is anthor question that if the value(a==7 in your example) does not exists in the array. It return the max array index, how solve it? Commented Apr 1, 2017 at 7:54
  • So what must it return if there isn't any element with the value 7 in the array? Commented Apr 2, 2017 at 7:50

2 Answers 2

4

First of all, to get the index of the last occurrence of 7, you would use:

import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1])

indices = np.argwhere(a== 7)
last_index = indices[-1]
# 10

Now if you had a 3-dimensional array, you can still use np.argwhere to get occurrences of 7, but each occurrence will be in 3-dimensional space. To get the last occurrence of 7, again you would write

b = np.tile(a.reshape(17,1,1), reps=(1,30,30))
np.argwhere(b==7)[-1]
# [10 29 29]

which returns exactly what you would expect.

Sign up to request clarification or add additional context in comments.

1 Comment

2d array, I want to apply the same way on axia =0. Like every b[:, i,j] loop i and j.
3

To get the last index, we can flip the order along all axes and then use np.argmax() on the matches. The idea with flipping is to make use of the efficient np.argmax that gets us the first matching index.

Thus, an implementation would be -

def last_match_index(a, value):
    idx = np.array(np.unravel_index(((a==value)[::-1,::-1,::-1]).argmax(), a.shape))
    return a.shape - idx - 1

Runtime test -

In [180]: a = np.random.randint(0,10,(100,100,100))

In [181]: last_match_index(a,7)
Out[181]: array([99, 99, 89])

# @waterboy5281's argwhere soln
In [182]: np.argwhere(a==7)[-1]
Out[182]: array([99, 99, 89])

In [183]: %timeit np.argwhere(a==7)[-1]
100 loops, best of 3: 4.67 ms per loop

In [184]: %timeit last_match_index(a,7)
1000 loops, best of 3: 861 µs per loop

If you are looking to get the last index along an axis, say axis=0 and iterate along two axes, let's say the last two axes, we could employ the same methodology -

a.shape[0] - (a==7)[::-1,:,:].argmax(0) - 1

Sample run -

In [158]: a = np.random.randint(4,8,(100,100,100))
     ...: m,n,r = a.shape
     ...: out = np.full((n,r),np.nan)
     ...: for i in range(n):
     ...:     for j in range(r):
     ...:         out[i,j] = np.argwhere(a[:,i,j]==7)[-1]
     ...:         

In [159]: out1 = a.shape[0] - (a==7)[::-1,:,:].argmax(0) - 1

In [160]: np.allclose(out, out1)
Out[160]: True

2 Comments

It's return 1d array has three element. 2d array, I want to apply the same way on axia =0. Like every b[:, i,j] loop i and j.
@LiZiming Check out the edits added at the end of the post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.