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?

4 Answers 4

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])
Sign up to request clarification or add additional context in comments.

Comments

10

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]

Comments

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)]

Comments

0

TLDR: use mask.

Benchmark using given case:

import numpy as np


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

%%timeit
idx = [1, 2, 5]
np.delete(a,idx)
# 2.06 µs ± 10.8 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

%%timeit
mask = np.ones(a.size, dtype=bool)
mask[idx] = False
a[mask]
# 1.51 µs ± 7.62 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

%%timeit
a[~np.in1d(np.arange(a.size), idx)]
# 14.8 µs ± 187 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

Comments

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.