Reputation: 42459
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?
Upvotes: 14
Views: 7742
Reputation: 2167
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)
Upvotes: 0
Reputation: 231738
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])
Upvotes: 14
Reputation: 221754
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)]
Upvotes: 5
Reputation: 310287
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]
Upvotes: 10