RPT
RPT

Reputation: 748

Delete multiple elements from a 3-D numpy array

I have a 3D array:

array([[[ 0.61795117,  0.34560273],
        [ 0.60095554,  0.313913  ],
        [ 0.56190875,  0.27450137],
        [ 0.53021642,  0.26212656],
        [ 0.49034335,  0.25858353],
        [ 0.44450648,  0.26146402],
        [ 0.41882064,  0.26448245],
        [ 0.39206795,  0.26703482],
        [ 0.37275912,  0.27370546]],

       [[ 0.62495791,  0.3120504 ],
        [ 0.60739456,  0.2823137 ],
        [ 0.58004256,  0.25910831],
        [ 0.54361132,  0.25084742],
        [ 0.49346121,  0.24739456],
        [ 0.44806806,  0.24990211],
        [ 0.40776521,  0.25205095],
        [ 0.37056546,  0.256433  ],
        [ 0.34548124,  0.26043473]],

       [[ 0.65452639,  0.26129899],
        [ 0.62969364,  0.25388184],
        [ 0.59575798,  0.24279791],
        [ 0.56249134,  0.23879938],
        [ 0.50719102,  0.23659991],
        [ 0.4391442 ,  0.23682689],
        [ 0.39447801,  0.23831357],
        [ 0.35186027,  0.24433696],
        [ 0.31920393,  0.25020494]]])

I have a list of indexes:

[(0, 0),(0, 1),(0, 2),(0, 3),(0, 4),(0, 5),(0, 6),(0, 7),(0, 8),(1, 0),(1, 3),(1, 6),(2, 0),(1, 1)]

I am trying to delete the rows in the 3D array that each tuple points to.

I have tried, but unsuccessful

np.delete(array, indexes, axis=0)

Any suggestions?

Upvotes: 1

Views: 315

Answers (2)

Banana
Banana

Reputation: 1187

Probably not the most beautiful solution, but you can use boolean indexing (that is, if those lists always have a similar shape to what you showed). I explicitly assume that the elements you want to delete correspond to the subarrays of size two here, then:

indices = [(0, 0),(0, 1),(0, 2),(0, 3),(0, 4),(0, 5),(0, 6),(0, 7),(0, 8),(1, 0),(1, 3),(1, 6),(2, 0),(1, 1)]
ind = np.array(indices)
idx = np.ones(arr.shape[0:2],dtype= bool) # here I assume the shape
idx[ind[:,0],ind[:,1]] = False
print(arr[idx])

Will print the array you want

Edit: The main problem is that, even with a nice mask like

indices = [(0, 0),(0, 1),(0, 2),(0, 3),(0, 4),(0, 5),(0, 6),(0, 7),(0, 8),(1, 0),(1, 3),(1, 6),(2, 0),(1, 1)]
im,jm = zip(*indices)
idx = np.ones_like(arr,dtype=bool)
idx[im,jm] = False

The number of "rows" you want to take out varies in the different entries of the first dimension. At first your array is of dimension (3,7,2). Then, along the first dimensionyou want to delete different numbers of rows for all 3 subarrays, and thus you can't reshape it into something of similar shape ( like (3,5,2) or whatever). That is also the main problem with trying to use delete here, I believe. So even when you apply:

newarr = arr[idx]

the array will contain the elements you want, but will be flattened. If you can make out a rule for proper reshaping, for example you always know the size of the innermost arrays (and those are the ones that will be deleted) which is in this case 2, you could use the mask and do

newarr = arr[idx].reshape(-1,2)

for a more general solution

Upvotes: 3

Pratik Kumar
Pratik Kumar

Reputation: 2231

why don't you convert your array arr into a list first then delete the elements:

a=arr.tolist()
for i in indexes:
  x,y=i
  del(a[x][y])

Upvotes: 0

Related Questions