2

I would like to slice a numpy array so that I can exclude a single element from it.

For example, like this:

a = numpy.array([1,2,3,4,5])
b = a[0:1::3:4]
b = [1 2 4 5]

Only that this does not work, so either I am doing something wrong, or it isn't possible.

Rory Daulton
  • 21,934
  • 6
  • 42
  • 50
John
  • 465
  • 1
  • 6
  • 13
  • The questions of which this is allegedly duplicate deals with the product of the entires specifically, though. – John Jun 09 '19 at 00:28
  • bad duplicate: https://stackoverflow.com/questions/48061508/numpy-slicing-all-except-one-array-entry. This poster doesn't want a product. – hpaulj Jun 09 '19 at 00:29
  • 1
    There is a `np.delete` function. Internally though it will just join two separate slices. You can't do this with just one slice. The result must be a `copy`, not a `view`. – hpaulj Jun 09 '19 at 00:30
  • @hpaulj : I can't vote again. Kindly close it as a duplicate of https://stackoverflow.com/questions/19286657/index-all-except-one-item-in-python – Sheldore Jun 09 '19 at 00:32
  • numpy.delete creates a copy, which is too slow for me. In reality I need to delete 1 entry from a million-entry array several hundred thousand times. – John Jun 09 '19 at 00:33
  • 2
    Can you delete several hundred thousand elements at one time? You might, for example want to set a mask, True for the keep values, False for deletes, and then do one boolean index. Deleting one item at a time is not going to be efficient, not even with lists. – hpaulj Jun 09 '19 at 01:22

4 Answers4

2

If you are going to repeatedly 'delete' one item at a time, I'd suggest using a boolean mask:

In [493]: a = np.arange(100)                                                                           
In [494]: mask = np.ones(a.shape, dtype=bool)                                                          
In [495]: for i in [2,5,9,20,3,26,40,60]: 
     ...:     mask[i]=0 
     ...: a1 = a[mask]                                                                                 
In [496]: a1.shape                                                                                     
Out[496]: (92,)

That's effectively what np.delete does when given a list or array of deletes

In [497]: a2 = np.delete(a, [2,5,9,20,3,26,40,60])                                                     
In [498]: np.allclose(a1,a2)                                                                           
Out[498]: True

For a single element is joins two slices - either by concatenate or copying to result array of the right size. In all cases we have to make a new array.

One exclusion or many, you seek an discontinuous selection of the elements of the original. That can't be produced with a view, which uses shape and strides to select a regular subset of the original.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • I realize this is outside the scope of my original question, but after the first mask I need to do further ones, e.g. remove other elements from the array. That means I would need to create a new mask each time, no? Also, I am modifying the array on each step too, so masking the original array with a mask with several 0s doesn't work either. – John Jun 09 '19 at 02:42
  • What else are you doing with the array? I'm not sure numpy arrays are the right data structure for you. – hpaulj Jun 09 '19 at 03:19
0

You need to do something like below

 a =  np.array([1,2,3,4,5])
 b = a[:2]
 c = a[3:]
 print ( b )
 print ( c )
 z= np.concatenate((b,c),axis=None)
 print ( z )

Output:
[1 2]
[4 5]
[1 2 4 5]

Hence here everything other than 3 is in new numpy.ndarray z here. Other way is to use to use np.delete function as shown in one the answers where you can provide list of indexes to be deleted inside the [] where list contains coma seperated index to be deleted.

   a =  np.array([15,14,13,12,11])
   a4=np.delete(a,[1,4])
   print(a4)

   output is :
   [15 13 12]
Invictus
  • 4,028
  • 10
  • 50
  • 80
0
import numpy as np

a = np.array([1,2,3,4,5])
result = np.delete(a,2)
result = [1,2,4,5]
RAGHHURAAMM
  • 1,099
  • 7
  • 15
-1

You could always use sets of slicing

b = a[:2]+a[3:]

Will return [1, 2, 4, 5]

for a numpy return value you could do 2 slices and concatenate the results.

 b = a[3:]
 c = a[:2]
 numpy.concatenate([c,b])

Will return

array([1, 2, 4, 5])
BillyN
  • 185
  • 2
  • 10