Reputation: 740
What is the most concise (compact) way to give the complement of a numpy.array
slice? Contrary to a previous post I have no speed consideration but ease of use/readability/generality in mind.
As an example, take the array A=np.array([1,2,3,4,5,6])
. I am looking for the complement of A[start:stop]
, e.g., for the complement of A[2:4]
which would be "comp of A[2:4]"=array([1,2,3,6])
. I am looking for a solution that works regardless of the content type. So A could contain also arrays, str and ideally in principle be of any dimension for which the normal [start:stop] slice operation works too.
Without claiming generality, this is what I currently use:
def comp(A,start,stop):
if A.ndim == 1:
out = np.hstack((A[0:start],A[stop:]))
else:
out = np.vstack((A[0:start],A[stop:]))
return out
Upvotes: 3
Views: 1282
Reputation: 231530
The r_
solution that @Divakar
proposes is a concise one for numpy
, but it won't generalize to other classes.
In [195]: np.r_[0:2,4:6]
Out[195]: array([0, 1, 4, 5])
It generates a list of indices that you want to keep, essentially concatenate
of np.arange(0,2)
and np.arange(4,6)
. Indexing with the list is advanced indexing
, which makes a copy.
You can't use such a list to index a Python list
or string
. They can only index elements. To use it on list:
[alist[i] for i in np.r_[0:2,4:6]]
But lists have a delete syntax alist[2:4]=[]
Strings don't have that because they are immutable.
A more universal approach is to concatenate/join two slices
np.concatenate([arr[0:2], arr[4:6]])
alist[0:2] + alist[4:6]
astr[0:2] + astr[4:6]
np.concatenate([arr[:, 0:2], arr[:, 4:6]], axis=1)
Your hstack/vstack
code can be rolled into one with
np.concatenate((A[0:start],A[stop:]),axis=0)
since you are joining the slices on the first dimension in both cases.
The complement of a 2d slice:
arr[2:4, 2:4]
can't be a 2d array. Different numbers of elements are left in each row.
Upvotes: 2