3

I am trying to figure out a way to take a numpy array of integers, then change the entries such that the smallest is 0, the second smallest is 1, etc.

E.g.

Start with this

In [13]: a = numpy.array([[1, 2, 10],[1, 2, 99]])

In [14]: a
Out[14]: 
array([[ 1,  2, 10],
       [ 1,  2, 99]])

And get this:

array([[ 0,  1, 2],
       [ 0,  1, 3]])

I can start to see the way through with numpy.unique(), e.g.

In [19]: range(len(b))
Out[19]: [0, 1, 2, 3]

In [20]: b = numpy.unique(a)

In [21]: b
Out[21]: array([ 1,  2, 10, 99])

In [22]: c = range(len(b))

In [23]: c
Out[23]: [0, 1, 2, 3]

Seems like I should now be able to use b and c to translate from one array to the other. But what's the best (and quickest) way to do this?

1

3 Answers 3

5

Don't know about quickest, but if you have scipy available, you can use scipy.stats.rankdata:

>>> a = np.array([[1, 2, 10],[1, 2, 99]])
>>> scipy.stats.rankdata(a,'dense').reshape(a.shape)-1
array([[ 0.,  1.,  2.],
       [ 0.,  1.,  3.]])

(The reshape is needed because it flattens the data first, and the -1 because it starts its ranks at 1.)

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

1 Comment

Thanks, and thanks particularly for the added explanations. Very neat solution.
2

the most straight forward way is using argsort()

a = numpy.array([0, 1, 1, 2])
u, ind = numpy.unique(a, return_inverse = True)
u = u.argsort().argsort()
ret = u[ind]

3 Comments

That won't work if there are repeated indices, e.g. [0, 1, 1, 2].
notice that np.unique always returns sorted values so u.argsort().argsort() == np.arange(len(u)).
@BiRico is right, so you can just use ind and drop the last two lines.
2

I'll give you two choices, the first seems cleaner somehow:

a = numpy.array([[1, 2, 10],[1, 2, 99]])
uniq, inv = numpy.unique(a, return_inverse=True)
result = inv.reshape(a.shape)

I like this one because it works with older versions of numpy that don't have return_inverse:

a = numpy.array([[1, 2, 10],[1, 2, 99]])
uniq = numpy.unique(a)
result = uniq.searchsorted(a)

Comments

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.