0

Suppose I have an array of integers x and I want to do the following:

  1. get an array unique_x of the unique values of x
  2. build an array y in which y[i] is the index in unique_x of the value x[i].

I managed to do this as follows:

import numpy as np

unique_x = np.unique(x)
y = np.zeros_like(x)
for k, value in unique_x:
   indices, = np.nonzero(x == value)
   y[indices] = k

My question is: is there a way to do this using only numpy builtin functions and some slicing? I have a feeling that this loop won't be as fast as it could be if this was done with numpy builtins.

1 Answer 1

2

If np.unique() does what you want it to (returns only the first occurence of each element; it doesn't return only those elements which occur once), you can do use the return_index argument:

In [1]: x = array([1, 1, 2, 3, 4, 4, 5, 6, 2, 1])
In [2]: unique_x, unique_indexes = np.unique(x, return_index=True)
In [3]: unique_x
Out[3]: array([1, 2, 3, 4, 5, 6])
In [4]: unique_indexes
Out[4]: array([0, 2, 3, 4, 6, 7])

(x does not need to be sorted, but unique_x will be). If you want the indicies necessary to reconstruct x from unique_x, on the other hand, you can use the return_inverse argument, as pointed out by @xtofl:

In [5]: unique_x, unique_inverse = np.unique(x, return_inverse=True)
In [6]: unique_inverse
Out[6]: array([0, 0, 1, 2, 3, 3, 4, 5, 1, 0])
Sign up to request clarification or add additional context in comments.

3 Comments

does x have to be sorted for this to work? (would it work with e.g. [1, 2, 1])
... I believe what OP wants is return_inverse=True.
I've edited my answer with some more information for the OP - thanks.

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.