0

Hi basically I want to input a 2D array and then create a new ranked array with the values from lowest to highest.

The array I am using is an elevation raster converted to a numpyarray. This array has a value for elevation. I only want to sort by elevation. Below is how far I got with the code, but it is not generating what I want!

import arcpy
import numpy

array = arcpy.RasterToNumPyArray(r"C:\Current\SedMod\SedModv3\TestModel.gdb\Smallprepfin_Clip")

order = array.argsort()
ranks = order.argsort()

print ranks

Thanks for any help!

Additional clarification:

I want to sort all the values contained within the array from the highest value to the lowest value but maintain the indices and shape of the array.

i.e the highest value(elevation) would be rank 1 and the lowest rank 100 if there are 100 values!

Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234
Nick Jones
  • 225
  • 4
  • 13
  • Do you want the result to be a 1D array ? – hivert Jul 23 '13 at 15:30
  • Additional clarification: I want to sort all the values contained within the array from the highest value to the lowest value but maintain the indices and shape of the array. i.e the highest value(elevation) would be rank 1 and the lowest rank 100 if there are 100 values! – Nick Jones Jul 23 '13 at 15:36

2 Answers2

2

How about something like this:

>>> a
array([[ 0.76303184,  0.17748702,  0.89365504,  0.07221609],
       [ 0.12267359,  0.56999037,  0.42877407,  0.8875015 ],
       [ 0.38178661,  0.57648393,  0.47056551,  0.03178402],
       [ 0.03606595,  0.93597727,  0.02199706,  0.73906879]])
>>> a.ravel().argsort().argsort().reshape(a.shape)
array([[12,  5, 14,  3],
       [ 4,  9,  7, 13],
       [ 6, 10,  8,  1],
       [ 2, 15,  0, 11]])

Not super happy with this, there is likely a better way.

Daniel
  • 19,179
  • 7
  • 60
  • 74
  • Additional clarification: I want to sort all the values contained within the array from the highest value to the lowest value but maintain the indices and shape of the array. i.e the highest value(elevation) would be rank 1 and the lowest rank 100 if there are 100 values! – Nick Jones Jul 23 '13 at 15:35
  • so for your array I would end up with something like: array([[ 14, 13, 15, 7], [ 2, 12, 1, 16 ], [ 5, 6, 11, 3], [4, 9, 8, 10]]) – Nick Jones Jul 23 '13 at 15:36
  • Hmmm I can't seem to get it to work can you write it in code like this: import arcpy import numpy array = ([[ 0.76303184, 0.17748702, 0.89365504, 0.07221609], [ 0.12267359, 0.56999037, 0.42877407, 0.8875015 ], [ 0.38178661, 0.57648393, 0.47056551, 0.03178402], [ 0.03606595, 0.93597727, 0.02199706, 0.73906879]]) sorted_array = numpy.ravel(a).argsort().argsort().reshape(a.shape) print sorted_array – Nick Jones Jul 23 '13 at 16:04
  • >>> a [[0.76303184, 0.17748702, 0.89365504, 0.07221609], [0.12267359, 0.56999037, 0.42877407, 0.8875015], [0.38178661, 0.57648393, 0.47056551, 0.03178402], [0.03606595, 0.93597727, 0.02199706, 0.73906879]] >>> a.ravel().argsort().argsort().reshape(a.shape) Traceback (most recent call last): File "", line 1, in AttributeError: 'list' object has no attribute 'ravel' – Nick Jones Jul 23 '13 at 16:06
  • You need to convert the list of list to a numpy array. `array=numpy.array(array)`. On this note I wouldnt name an array `array` perhaps `arr` or some other variable. – Daniel Jul 23 '13 at 16:07
1

You need scipy.stats.rankdata for this

from scipy.stats import rankdata
ranks=rankdata(a).reshape(a.shape)

To rank from highest to lowest, invert the input a

ranks=rankdata(a.max()-a).reshape(a.shape)
Jason
  • 2,950
  • 2
  • 30
  • 50