Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy Indexing: Return the rest

Tags:

A simply example of numpy indexing:

In: a = numpy.arange(10) In: sel_id = numpy.arange(5) In: a[sel_id] Out: array([0,1,2,3,4]) 

How do I return the rest of the array that are not indexed by sel_id? What I can think of is:

In: numpy.array([x for x in a if x not in a[id]]) out: array([5,6,7,8,9]) 

Is there any easier way?

like image 484
CJLam Avatar asked Sep 20 '12 17:09

CJLam


2 Answers

For this simple 1D case, I'd actually use a boolean mask:

a = numpy.arange(10) include_index = numpy.arange(4) include_idx = set(include_index)  #Set is more efficient, but doesn't reorder your elements if that is desireable mask = numpy.array([(i in include_idx) for i in xrange(len(a))]) 

Now you can get your values:

included = a[mask]  # array([0, 1, 2, 3]) excluded = a[~mask] # array([4, 5, 6, 7, 8, 9]) 

Note that a[mask] doesn't necessarily yield the same thing as a[include_index] since the order of include_index matters for the output in that scenario (it should be roughly equivalent to a[sorted(include_index)]). However, since the order of your excluded items isn't well defined, this should work Ok.


EDIT

A better way to create the mask is:

mask = np.zeros(a.shape,dtype=bool) mask[include_idx] = True 

(thanks to seberg).

like image 125
mgilson Avatar answered Oct 15 '22 19:10

mgilson


You can do this nicely with boolean masks:

a = numpy.arange(10)  mask = np.ones(len(a), dtype=bool) # all elements included/True. mask[[7,2,8]] = False              # Set unwanted elements to False  print a[mask] # Gives (removing entries 7, 2 and 8): [0 1 3 4 5 6 9] 

Addition (taken from @mgilson). The binary mask created can be used nicely to get back the original slices with a[~mask] however this is only the same if the original indices were sorted.


EDIT: Moved down, as I had to realize that I would consider np.delete buggy at this time (Sep. 2012).

You could also use np.delete, though masks are more powerful (and in the future I think that should be an OK option). At the moment however its slower then the above, and will create unexpected results with negative indices (or steps when given a slice).

print np.delete(a, [7,2,8]) 
like image 45
seberg Avatar answered Oct 15 '22 18:10

seberg