Marco
Marco

Reputation: 242

How to split an 2D array, creating arrays from "row to row" values

I want to split an 2D array this way:

Example.

From this 4x4 2D array:

np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])

Create these four 2x2 2D arrays:

np.array([[1,2],[3,4]])
np.array([[5,6],[7,8]])
np.array([[9,10],[11,12]])
np.array([[13,14],[15,16]])

In a general case, from a NxN 2D array (square arrays) create 2D arrays of KxK shape, as many as possible.

Just to be more precise: to create the output array, not necessarily it will be made of all values from the row.

Example:

From a 2D 8x8 array, with values from 1 to 64, if I want to split this array in 2D 2x2 arrays, the first row from 8x8 array is a row from 1 to 8, and the first output 2D 2x2 array will be np.array([[1,2],[3,4]]), and the second output 2D 2x2 array will be np.array([[5,6],[7,8]])... It continues until the last output 2D array, that will be np.array([[61,62],[63,64]]). Look that each 2D 2x2 array was not filled with all the values from the row (CORRECT).

There is a Numpy method that do this?

Upvotes: 3

Views: 2309

Answers (3)

MSeifert
MSeifert

Reputation: 152870

To get your desired output, you need to reshape to a 3D array and then unpack the first dimension:

>>> inp = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
>>> list(inp.reshape(-1, 2, 2))
[array([[1, 2],
        [3, 4]]), 
 array([[5, 6],
        [7, 8]]), 
 array([[ 9, 10],
        [11, 12]]), 
 array([[13, 14],
        [15, 16]])]

You can also unpack using = if you want to store the arrays in different variables instead of in one list of arrays:

>>> out1, out2, out3, out4 = inp.reshape(-1, 2, 2)
>>> out1
array([[1, 2],
       [3, 4]])

If you're okay with a 3D array containing your 2D 2x2 arrays you don't need unpacking or the list() call:

>>> inp.reshape(-1, 2, 2)
array([[[ 1,  2],
        [ 3,  4]],

       [[ 5,  6],
        [ 7,  8]],

       [[ 9, 10],
        [11, 12]],

       [[13, 14],
        [15, 16]]])

The -1 is a special value for reshape. As the documentation states:

One shape dimension can be -1. In this case, the value is inferred from the length of the array and remaining dimensions.


If you want it more general, just take the square root of the row-length and use that as argument for reshape:

>>> inp = np.ones((8, 8))  # 8x8 array
>>> square_shape = 2
>>> inp.reshape(-1, square_shape, square_shape)  # 16 2x2 arrays

>>> square_shape = 4
>>> inp.reshape(-1, square_shape, square_shape)  # 4 4x4 arrays

Upvotes: 2

Cédric Julien
Cédric Julien

Reputation: 80851

You're probably looking for something like numpy.reshape.

In your example:

numpy.array([[1,2,3,4], [5,6,7,8]]).reshape(2,4)
>>>array([[1,2], [3,4], [5,6], [7,8]])

Or, as suggested by @MSeifert, using -1 as final dimension will let numpy do the division by itself:

numpy.array([[1,2,3,4], [5,6,7,8]]).reshape(2,-1)
>>>array([[1,2], [3,4], [5,6], [7,8]])

Upvotes: 3

SudipM
SudipM

Reputation: 426

If you want to split it row wise, you may do np.reshape(arr,(2,2), order='C') If you want to split it column wise, you may do not.reshape(arr,(2,2), order='F')

Upvotes: 0

Related Questions