45

Say I have some long array and a list of indices. How can I select everything except those indices? I found a solution but it is not elegant:

import numpy as np
x = np.array([0,10,20,30,40,50,60])
exclude = [1, 3, 5]
print x[list(set(range(len(x))) - set(exclude))]
Georgy
  • 12,464
  • 7
  • 65
  • 73
kilojoules
  • 9,768
  • 18
  • 77
  • 149

4 Answers4

53

This is what numpy.delete does. (It doesn't modify the input array, so you don't have to worry about that.)

In [4]: np.delete(x, exclude)
Out[4]: array([ 0, 20, 40, 60])
Sergei Kozelko
  • 691
  • 4
  • 17
user2357112
  • 260,549
  • 28
  • 431
  • 505
28

np.delete does various things depending what you give it, but in a case like this it uses a mask like:

In [604]: mask = np.ones(x.shape, bool)
In [605]: mask[exclude] = False
In [606]: mask
Out[606]: array([ True, False,  True, False,  True, False,  True], dtype=bool)
In [607]: x[mask]
Out[607]: array([ 0, 20, 40, 60])
hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • 1
    The best solution and one that I assume is the most vectorizable and efficient. – Joey Carson Nov 29 '18 at 20:18
  • @JoeyCarson, can you please explain why it's better than accepted one? – Shihab Shahriar Khan Nov 16 '19 at 12:43
  • 1
    @ShihabShahriarKhan According to [numpy.delete](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.delete.html) documentation, "Often it is preferable to use a boolean mask ... [It] is equivalent to np.delete(...), but allows further use of mask." – nish-ant Feb 18 '20 at 10:14
8

np.in1d or np.isin to create boolean index based on exclude could be an alternative:

x[~np.isin(np.arange(len(x)), exclude)]
# array([ 0, 20, 40, 60])

x[~np.in1d(np.arange(len(x)), exclude)]
# array([ 0, 20, 40, 60])
Psidom
  • 209,562
  • 33
  • 339
  • 356
  • 1
    This has the advantage of being usable in assignment. Still, wondering if there isn't something more efficient... – Paul Panzer Nov 28 '17 at 21:21
-1

You can also use a list comprehension for the index

>>> x[[z for z in range(x.size) if not z in exclude]]
array([ 0, 20, 40, 60])
percusse
  • 3,006
  • 1
  • 14
  • 28