1'' - 1 year ago 73

Python Question

Is there a single Numpy function that is equivalent to

`[array == value for value in np.unique(array)]`

or

`[np.where(array == value) for value in np.unique(array)]`

Or if not, a more efficient way to do this? These iterate through the array

`len(np.unique(array))`

`indices = defaultdict(list)`

for index, value in enumerate(array):

indices[value].append(index)

I'd like a solution that doesn't require an explicit for loop.

Answer Source

If what you want is a mask with multiple unique number conditions, you can do it using `return_inverse`

from np.unique:

Having a sample array

```
>>> a = np.random.randint(5, 10, size=100) # 100 [5-10) random numbers
```

And its unique numbers and inverse mapping

```
>>> unique, inverse = np.unique(a, return_inverse=True)
```

We can create a container with extra dimensions (`a.shape`

+ 1 dimension foe each unique number)

```
>>> indexes = np.zeros((a.shape[0], unique.size), dtype=np.bool)
```

And finally, fill the array with the inverse mapping:

```
>>> indexes[np.arange(a.size), inverse] = True
```

The `indexes`

map contains `True`

in the last dimension corresponding to the index of the *unique number* that it matches (the order in the `unique`

array).

```
>>> indexes[:3, :]
array([[False, False, False, False, True],
[ True, False, False, False, False],
[False, False, False, True, False]], dtype=bool)
```

Each row corresponds to the index of your original array `a`

and each column corresponds to a *unique number*.