3

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?

9
  • So, the output would be one multi-dimensional array of shape (4,2,2)? Commented Oct 10, 2017 at 12:04
  • 3
    Could you make your input (currently looks like 4 arrays) and output (looks like 8 arrays) less ambiguous? It's hard to know what you're looking for if it's unclear what exactly the input and output is. Commented Oct 10, 2017 at 12:05
  • @MSeifert ok, I have edited. Commented Oct 10, 2017 at 12:32
  • @Divakar no, the output would be four 2D array (2x2). Commented Oct 10, 2017 at 12:37
  • 1
    I should have just entered the direct code. Commented Oct 10, 2017 at 12:49

3 Answers 3

3

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]])
Sign up to request clarification or add additional context in comments.

5 Comments

Should also work with .reshape(2, -1). That avoids hardcoding the "shape" of the second dimension.
In the example he hardcoded 4 as length of the second dimension. That will restrict it to arrays of size 8. With -1 it will work for all arrays that have a size that is divisible by 2. The comment asking for this information has been deleted but I'll keep it here in case it's of interest to anyone.
@Cédric Julien this code not get the desired output. From te example, If the input is a 2D 4x4 array, and if I want to split it in 2D 2x2 arrays, the first output array will be np.array([[1,2], [3,4]]). In your example, you get a 2D 2x4 array. The desired output from the first 2D 2x2 array would be no.array([[1,2], [3,4]]), not a single 2D 4x2 array.
@Marco : well, you changed/specified your question after my answer. I'm not sure you can automatically split into the maximum KxK arrays. You'll have to specify at least 1 dimension of the final shape.
Sure, i always define it. Example: output 2D 2x2 arrays, or 3x3, any square array.
2

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

8 Comments

excelent. I could put this in a "for" to work with each output array, right?
@Marco Yes, if you use the list or 3D array approach you can access each of the output arrays with a for loop over the list or array. :)
ok, thanks. Just to confirm your answer, to create the output array, not necessarily it will be made of all values from the row, right? 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]])... So, It was not filled with all the values from the row (CORRECT).
@Marco Sorry, but you lost me there. I thought your intention was to make a square array of the values of one row, not to create square arrays (potentially) spanning multiple rows of the original. Maybe your example was just too simple or I'm misunderstanding your intent.
yes, maybe the example was simple. I will edit the question, adding this above comment to clarify the question.
|
0

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')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.