Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple dimension selection in numpy using range finishes with unexpected behaviour

Let's assume that x is a 3-dimensional numpy.array with shape (3, 22400, 22400). I'd like to crop a part of this array and to do this I'm performing the following operations:

x_range = range(0, 224)
y_range = range(0, 224)

Now, when I do the following selection, the behaviour seems to be correct:

x[:, x_range, :].shape == (3, 224, 22400)

But with multiple selection something weird happens:

x[:, x_range, y_range].shape == (3, 224)

The problem seems to arise around the issue that range is a generator, but I don't understand what's the reason of such behaviour.

System details:

print(sys.version)
3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul  5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)]
print(numpy.version.version)
1.11.3
like image 253
Marcin Możejko Avatar asked Sep 08 '25 12:09

Marcin Możejko


1 Answers

Issue

You were triggering advanced-indexing there causing unintended result. Also, the crop box size used was of square shape(224, 224). So, didn't throw any error there.

Let's try it out with a non-square cropping -

In [40]: x = np.random.randint(11,99,(3,1000,1000))

In [41]: x_range = range(0, 224)
    ...: y_range = range(0, 324)  # Edited from 224 to 324
    ...: 

In [42]: x[:, x_range, y_range]
Traceback (most recent call last):

  File "<ipython-input-42-1bf422b8091c>", line 1, in <module>
    x[:, x_range, y_range]

IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (224,) (324,) 

Solution

To get the desired result, you could use np.ix_ -

x[np.ix_(np.arange(x.shape[0]),x_range,y_range)]

Sample run -

In [34]: x = np.random.randint(11,99,(3,10,10))

In [35]: x_range = range(3, 8) # length = 5
    ...: y_range = range(5, 9) # length = 4
    ...: 

In [36]: out = x[np.ix_(np.arange(x.shape[0]),x_range,y_range)]

In [37]: out.shape
Out[37]: (3, 5, 4)
like image 84
Divakar Avatar answered Sep 10 '25 05:09

Divakar