Removing multiple fragments from a numpy array

I have a given numpy array and a list containing several slice objects (alternatively containing (start, end) tuples). I want to remove the position of the slice object from the original array and get the second array with the remaining values.

Toy example:

 myarray = np.arange(20) array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) mylist=(slice(2,4),slice(15,19)) 

Do something and the result should be

 array([0, 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) 

An array can be several hundred thousand, a list of slice objects can contain several thousand elements, and I often need to perform an operation, so speed is somewhat important.

Numpy removal doesn't accept fragment list, as far as I can see?

At the moment, I am generating an add-on to my list of slicer objects and slicing this, but generating the add-on is a somewhat inconvenient process in which I sort my list of slicers and then repeat it, creating the slicer objects of the padding as needed. I hope there is a more elegant way that I did not understand!

+6
source share
3 answers

You can use set() to determine which positions will be saved, and np.take() to get the corresponding values, doing something like:

 ind = np.indices(myarray.shape)[0] rm = np.hstack([ind[i] for i in mylist]) ans = np.take(myarray, sorted(set(ind)-set(rm))) 

Note that np.hstack() used to get a single array with all indexes to be deleted. This takes about half the time of @HYRY's solution.

+1
source

I can't think of a way to join slices cleanly; however, I think using composite is the way to go. Maybe try something like this:

 import numpy as np # Create test data n_data = 1000000 n_slices = 10000 data = np.arange(n_data) slices = [] for i in range(n_slices): r = np.random.randint(n_data-1000) slices.append(slice(r,r + np.random.randint(1000))) # Remove slices keep_mask = np.ones_like(data, dtype=bool) for slice in slices: keep_mask[slice] = False data = data[keep_mask] # or np.take, etc. 
+1
source

You can use np.r_[] to combine slices into an array:

 myarray = np.arange(20) mylist=(slice(2, 4),slice(15, 19)) np.delete(myarray, np.r_[tuple(mylist)]) 

output:

 array([ 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 19]) 

But I think it is not very fast.

+1
source

Source: https://habr.com/ru/post/971938/


All Articles