Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

return indices from filtered, sorted array with numpy

What is the most straightforward way to do the following in python/numpy?

  • begin with random array x
  • filter out elements x < .5
  • sort the remaining values by size
  • return indices of (original) x corresponding to these values
like image 615
anon01 Avatar asked Sep 30 '15 18:09

anon01


People also ask

How do I get the indices of sorted array NumPy?

We can get the indices of the sorted elements of a given array with the help of argsort() method. This function is used to perform an indirect sort along the given axis using the algorithm specified by the kind keyword.

What does NP Argwhere return?

argwhere() function is used to find the indices of array elements that are non-zero, grouped by element. Parameters : arr : [array_like] Input array. Return : [ndarray] Indices of elements that are non-zero.

Can you index a NumPy array?

Array indexing is the same as accessing an array element. You can access an array element by referring to its index number. The indexes in NumPy arrays start with 0, meaning that the first element has index 0, and the second has index 1 etc.

Is NumPy Argsort stable?

NumPy's np. argsort is able to do stable sorting through passing kind = 'stable' argument. Also np. argsort doesn't support reverse (descending) order.


3 Answers

Finding the mask of x < 0.5 and x.argsort() seemed like compulsory here. Once you have those two, you can sort the mask array using the sort indices and use this mask on the sort indices to get back the indices corresponding to sorted indices that satisfy the masked condition. Thus, you would be adding one more line of code, like so -

mask = x < 0.5
sort_idx = x.argsort()
out = sort_idx[mask[sort_idx]]

Sample step-by-step run -

In [56]: x
Out[56]: array([ 0.8974009 ,  0.30127187,  0.71187137,  0.04041124])

In [57]: mask
Out[57]: array([False,  True, False,  True], dtype=bool)

In [58]: sort_idx
Out[58]: array([3, 1, 2, 0])

In [59]: mask[sort_idx]
Out[59]: array([ True,  True, False, False], dtype=bool)

In [60]: sort_idx[mask[sort_idx]]
Out[60]: array([3, 1])
like image 92
Divakar Avatar answered Nov 11 '22 20:11

Divakar


Masked arrays are concise (but maybe not especially efficient)

x = np.random.rand(4);

inverse_mask = x < 0.5
m_x = np.ma.array(x, mask=np.logical_not(inverse_mask))
sorted_indeces = m_x.argsort(fill_value=1)
filtered_sorted_indeces = sorted_indeces[:np.sum(inverse_mask)]
like image 41
Waylon Flinn Avatar answered Nov 11 '22 22:11

Waylon Flinn


One solution:

  • created sorted index array (argsort)
  • create mask for sorted x less than threshold
  • apply mask to sorted index array

example:

import numpy as np

# x = np.random.rand(4)
x = np.array([0.96924269, 0.30592608, 0.03338015, 0.64815553])
solution = np.array([2, 1])

sorted_idx = np.argsort(x)
idx_mask = (x[sorted_idx] < 0.5)
sorted_filtered_idx = sorted_idx[idx_mask]

assert np.all(sorted_filtered_idx == solution)
like image 39
anon01 Avatar answered Nov 11 '22 21:11

anon01