Foad S. Farimani
Foad S. Farimani

Reputation: 14008

Cropping a NumPy array of an arbitrary dimension given two corners

There are several posts for slicing 2D and 3D NumPy arrays, but in my program dimension of the array is not known. Consider a NumPy ndarray A of arbitrary dimension n (positive integer), and shape D=[d1,...,dn] (dis nonnegative integers), For example:

import numpy as np

D=np.array([2,3,4,5])

A=np.random.rand(*D)

Now I need to extract a block of A starting from D1=[d11,...,d1n] to D2=[d21,...,d2n], where for all 0<i<=n : 0<=d1i<=d2i<=di . Something like:

A[D1:D2]

If I new n then I could simple use A[d11:d21,...,d1i:d2i,...,d1n:d2n], but that's not the case for me. I would appreciate if you could help me know what is the most efficient way of cropping A given D1 and D2.

Upvotes: 0

Views: 1061

Answers (1)

Aaron
Aaron

Reputation: 11075

The portion of the numpy indexing page that @Joe referred to is likely this:

Note
Remember that a slicing tuple can always be constructed as obj and used in the x[obj] notation. Slice objects can be used in the construction in place of the [start:stop:step] notation. For example, x[1:10:5,::-1] can also be implemented as:

obj = (slice(1,10,5), slice(None,None,-1))
x[obj]

This can be useful for constructing generic code that works on arrays of arbitrary dimension.

Using this concept you should be able to build your tuple of slices ahead of time then apply it to A.

obj = tuple(slice(D1[i], D2[i]) for i in range(D1.shape[0]))
A[obj]

Note* this is not actually using advanced indexing, as you are still providing a tuple of slice objects which is just the longhand / functional equivalent of using slices separated by colons and commas: A[d11:d21, ... Advanced indexing utilizes arrays of different datatypes rather than exclusively tuples of slice objects.

Upvotes: 1

Related Questions