Easy way to collapse the final sizes of a numpy array?

In Matlab, I can do the following:

X = randn(25,25,25); size(X(:,:)) ans = 25 625 

I often find that I want to quickly collapse the final sizes of the array and don't know how to do this in numpy.

I know I can do this:

 In [22]: x = np.random.randn(25,25,25) In [23]: x = x.reshape(x.shape[:-2] + (-1,)) In [24]: x.shape Out[24]: (25, 625) 

but x.reshape(x.shape[:-2] + (-1,)) much less concise (and requires more information about x ) than just doing x(:,:) .

I obviously tried a similar numpy indexing, but this does not work as desired:

 In [25]: x = np.random.randn(25,25,25) In [26]: x[:,:].shape Out[26]: (25, 25, 25) 

Any tips on how to briefly collapse the final dimensions of the array?

Edit: note that I am after the resulting array, not just its shape. I just use size() and x.shape in the examples above to indicate what an array is.

+5
source share
3 answers

What should happen with 4d or higher?

 octave:7> x=randn(25,25,25,25); octave:8> size(x(:,:)) ans = 25 15625 

Your (:,:) reduces it to 2 dimensions, combining the latter. The last dimension is where MATLAB automatically adds and collapses dimensions.

 In [605]: x=np.ones((25,25,25,25)) In [606]: x.reshape(x.shape[0],-1).shape # like Joe's Out[606]: (25, 15625) In [607]: x.reshape(x.shape[:-2]+(-1,)).shape Out[607]: (25, 25, 625) 

Your reshape example does something different from MATLAB, it just collapses the last 2. Collapsing it to two dimensions, such as MATLAB, is a simpler expression.

MATLAB is concise simply because your needs match its assumptions. The numpy equivalent is not so brief, but gives you more control

For example, to save the last measurement or combine dimensions 2 by 2:

 In [608]: x.reshape(-1,x.shape[-1]).shape Out[608]: (15625, 25) In [610]: x.reshape(-1,np.prod(x.shape[-2:])).shape Out[610]: (625, 625) 

What is equivalent to MATLAB?

 octave:24> size(reshape(x,[],size(x)(2:end))) ans = 15625 25 octave:31> size(reshape(x,[],prod(size(x)(3:end)))) 
+3
source

You can use np.hstack :

 >>> np.hstack(x).shape (25, 625) 

np.hstack ake a sequence of arrays and stack them horizontally to create a single array.

+1
source

It might be a little easier for you to use the shape attribute. For instance:

 import numpy as np x = np.random.randn(25, 25, 25) x.shape = x.shape[0], -1 print x.shape print x 

This is functionally equivalent to reshape (in the sense of organizing data, etc.). Obviously, this information still requires information about form x , but this is a more concise way of handling the change.

+1
source

All Articles