Hi, On Fri, Aug 3, 2012 at 7:02 PM, Angus McMorland <amcm...@gmail.com> wrote:
> On 3 August 2012 11:18, Jim Vickroy <jim.vick...@noaa.gov> wrote: > >> Hello everyone, >> >> I'm trying to determine the 2 greatest values, in a 3-d array, along one >> axis. >> >> Here is an approach: >> >> # ------------------------------------------------------ >> # procedure to determine greatest 2 values for 3rd dimension of 3-d >> array ... >> import numpy, numpy.ma >> xcnt, ycnt, zcnt = 2,3,4 # actual case is (1024, 1024, 8) >> p0 = numpy.empty ((xcnt,ycnt,zcnt)) >> for z in range (zcnt) : p0[:,:,z] = z*z >> zaxis = 2 # max >> values to be determined for 3rd axis >> p0max = numpy.max (p0, axis=zaxis) # max >> values for zaxis >> maxindices = numpy.argmax (p0, axis=zaxis) # >> indices of max values >> p1 = p0.copy() # work >> array to scan for 2nd highest values >> j, i = numpy.meshgrid (numpy.arange (ycnt), numpy.arange >> (xcnt)) >> p1[i,j,maxindices] = numpy.NaN # flag >> all max values >> p1 = numpy.ma.masked_where (numpy.isnan (p1), p1) # hide >> all max values >> p1max = numpy.max (p1, axis=zaxis) # 2nd >> highest values for zaxis >> # additional code to analyze p0max and p1max goes here >> # ------------------------------------------------------ >> >> I would appreciate feedback on a simpler approach -- e.g., one that does >> not require masked arrays and or use of magic values like NaN. >> >> Thanks, >> -- jv >> > > Here's a way that only uses argsort and fancy indexing: > > >>>a = np.random.randint(10, size=(3,3,3)) > >>>print a > > [[[0 3 8] > [4 2 8] > [8 6 3]] > > [[0 6 7] > [0 3 9] > [0 9 1]] > > [[7 9 7] > [5 2 9] > [9 3 3]]] > > >>>am = a.argsort(axis=2) > >>>maxs = a[np.arange(a.shape[0])[:,None], np.arange(a.shape[1])[None], > am[:,:,-1]] > >>>print maxs > > [[8 8 8] > [7 9 9] > [9 9 9]] > > >>>seconds = a[np.arange(a.shape[0])[:,None], np.arange(a.shape[1])[None], > am[:,:,-2]] > >>>print seconds > > [[3 4 6] > [6 3 1] > [7 5 3]] > > And to double check: > > >>>i, j = 0, 1 > >>>l = a[i, j,:] > >>>print l > > [4 2 8] > > >>>print np.max(a[i,j,:]), maxs[i,j] > > 8 8 > > >>>print l[np.argsort(l)][-2], second[i,j] > > 4 4 > > Good luck. > Here the np.indicies function may help a little bit, like: In []: a= randint(10, size= (3, 2, 4)) In []: a Out[]: array([[[1, 9, 6, 6], [0, 3, 4, 2]], [[4, 2, 4, 4], [5, 9, 4, 4]], [[6, 1, 4, 3], [5, 4, 5, 5]]]) In []: ndx= indices(a.shape) In []: # largest In []: a[a.argsort(0), ndx[1], ndx[2]][-1] Out[]: array([[6, 9, 6, 6], [5, 9, 5, 5]]) In []: # second largest In []: a[a.argsort(0), ndx[1], ndx[2]][-2] Out[]: array([[4, 2, 4, 4], [5, 4, 4, 4]]) My 2 cents, -eat > > Angus. > -- > AJC McMorland > Post-doctoral research fellow > Neurobiology, University of Pittsburgh > > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > http://mail.scipy.org/mailman/listinfo/numpy-discussion > >
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion