简体   繁体   中英

Find last value in numpy array

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM