Amanda
Amanda

Reputation: 2153

Deleting multiple elements at once from a numpy 2d array

Is there a way to delete from a numpy 2d array when I have the indexes? For example:

a = np.random.random((4,5))
idxs = [(0,1), (1,3), (2, 1), (3,4)]

I want to remove the indexes specified above. I tried:

np.delete(a, idxs)

but it just removes the top row.

To give an example, for the following input:

    [
        [0.15393912, 0.08129568, 0.34958515, 0.21266128, 0.92372852],
        [0.42450441, 0.1027468 , 0.13050591, 0.60279229, 0.41168151],
        [0.06330729, 0.60704682, 0.5340644 , 0.47580567, 0.42528617],
        [0.27122323, 0.42713967, 0.94541073, 0.21462462, 0.07293321]
    ]

and with the indexes as mentioned above, I want the result to be:

    [
        [0.15393912, 0.34958515, 0.21266128, 0.92372852],
        [0.42450441, 0.1027468 , 0.13050591, 0.41168151],
        [0.06330729, 0.5340644 , 0.47580567, 0.42528617],
        [0.27122323, 0.42713967, 0.94541073, 0.21462462]
    ]

Upvotes: 1

Views: 2073

Answers (4)

Paul Panzer
Paul Panzer

Reputation: 53029

Here is a method using np.where

import numpy as np
import operator as op

a = np.arange(20.0).reshape(4,5)
idxs = [(0,1), (1,3), (2, 1), (3,4)]

m,n = a.shape

# extract column indices
# there are simpler ways but this is fast
columns = np.fromiter(map(op.itemgetter(1),idxs),int,m)

# build decimated array
result = np.where(columns[...,None]>np.arange(n-1),a[...,:-1],a[...,1:])

result
# array([[ 0.,  2.,  3.,  4.],
#        [ 5.,  6.,  7.,  9.],
#        [10., 12., 13., 14.],
#        [15., 16., 17., 18.]])

Upvotes: 0

Mad Physicist
Mad Physicist

Reputation: 114330

Numpy doesn't know that you are removing exactly one element per row when you give it arbitrary indices like that. Since you do know that, I would suggest using a mask to shrink the array. Masking has the same problem: it doesn't assume anything about the shape of the result (because it can't in general), and returns a raveled array. You can reinstate the shape you want quite easily though. In fact, I would suggest removing the first element of each index entirely, since you have one per row:

 def remove_indices(a, idx):
     if len(idx) != len(idx): raise ValueError('Wrong number of indices')
     mask = np.ones(a.size, dtype=np.bool_)
     mask[np.arange(len(idx)), idx] = False
     return a[mask].reshape(a.shape[0], a.shape[1] - 1)

Upvotes: 0

Dev Khadka
Dev Khadka

Reputation: 5451

your index should be for flat array else it only works to remove a row or column.

Here is how you can convert index and use it

arr = np.array([
    [0.15393912, 0.08129568, 0.34958515, 0.21266128, 0.92372852],
    [0.42450441, 0.1027468 , 0.13050591, 0.60279229, 0.41168151],
    [0.06330729, 0.60704682, 0.5340644 , 0.47580567, 0.42528617],
    [0.27122323, 0.42713967, 0.94541073, 0.21462462, 0.07293321]
])

idxs = [(0,1), (1,3), (2, 1), (3,4)]

idxs = [i*arr.shape[1]+j for i, j in idxs]

np.delete(arr, idxs).reshape(4,4)

for reshaping you should remove the items such that there will be equal number of items and rows and columns after deletion

Upvotes: 3

abhilb
abhilb

Reputation: 5757

As the documentation says

Return a new array with sub-arrays along an axis deleted.

np.delete deletes a row or a column based on the value of the parameter axis.

Secondly np.delete expects int or array of ints as parameter and not a list of tuples.

you need to specify what the requirement is.

As @divakar suggested look at other answers on Stackoverflow regarding deleting individual items in numpy array.

Upvotes: -1

Related Questions