14

I want to do something similar to what was asked here NumPy array, change the values that are NOT in a list of indices, but not quite the same.

Consider a numpy array:

> a = np.array([0.2, 5.6, 88, 12, 1.3, 6, 8.9])

I know I can access its elements via a list of indexes, like:

> indxs = [1, 2, 5] 
> a[indxs]
array([  5.6,  88. ,   6. ])

But I also need to access those elements which are not in the indxs list. Naively, this is:

> a[not in indxs]
> array([0.2, 12, 1.3, 8.9])

What is the proper way to do this?

Community
  • 1
  • 1
Gabriel
  • 40,504
  • 73
  • 230
  • 404

3 Answers3

14
In [170]: a = np.array([0.2, 5.6, 88, 12, 1.3, 6, 8.9])
In [171]: idx=[1,2,5]
In [172]: a[idx]
Out[172]: array([  5.6,  88. ,   6. ])
In [173]: np.delete(a,idx)
Out[173]: array([  0.2,  12. ,   1.3,   8.9])

delete is more general than you really need, using different strategies depending on the inputs. I think in this case it uses the boolean mask approach (timings should be similar).

In [175]: mask=np.ones_like(a, bool)
In [176]: mask
Out[176]: array([ True,  True,  True,  True,  True,  True,  True], dtype=bool)
In [177]: mask[idx]=False
In [178]: mask
Out[178]: array([ True, False, False,  True,  True, False,  True], dtype=bool)
In [179]: a[mask]
Out[179]: array([  0.2,  12. ,   1.3,   8.9])
hpaulj
  • 221,503
  • 14
  • 230
  • 353
8

One way is to use a boolean mask and just invert the indices to be false:

mask = np.ones(a.size, dtype=bool)
mask[indxs] = False
a[mask]
mgilson
  • 300,191
  • 65
  • 633
  • 696
5

One approach with np.in1d to create the mask of the ones from indxs present and then inverting it and indexing the input array with it for the desired output -

a[~np.in1d(np.arange(a.size),indxs)]
Divakar
  • 218,885
  • 19
  • 262
  • 358