0

I have a small problem, as I am learning Python. I am trying to slice a 2D-array in a particular way : taking one item over two, but at each line we begin at a different index, for example if we have a = np.reshape(np.arange(16),(4,4)) , so

>>print(a) = [[ 0  1  2  3]
              [ 4  5  6  7]
              [ 8  9 10 11]
              [12 13 14 15]] 

We would like to end with

>>print(new_a) = [[ 0  2]
                  [ 5  7]
                  [ 8 10]
                  [13 15]]

I am sure that it is not too complicated, but I couldn't find the answer :( (I now how to slice a np-array, just not how to change each row)

Thank you and have a nice day !

3 Answers 3

2

As long as the dimensions of a are even, one can get this specific (checkerboard) pattern with np.einsum:

>>> np.einsum('jiki->jik', a.reshape(2, 2, 2, 2)).reshape(4, 2)
array([[ 0,  2],
       [ 5,  7],
       [ 8, 10],
       [13, 15]])

or, more generally

>>> a = np.arange(40).reshape(4, 10)
>>> np.einsum('jiki->jik', a.reshape(a.shape[0]//2, 2, -1, 2)).reshape(a.shape[0], -1)
array([[ 0,  2,  4,  6,  8],
       [11, 13, 15, 17, 19],
       [20, 22, 24, 26, 28],
       [31, 33, 35, 37, 39]])
Sign up to request clarification or add additional context in comments.

Comments

0

You can use slicing with steps. Do this from 0 and from 1 with step size 2. This will give you two separate arrays, you can then do the work and join them back.

I am pretty new to numpy so there may be a better approach.

4 Comments

Seems good, but how can you join them "one row over two" ? I mean, if we have b = a[::2,::2] and c[1::2,1::2], we would want a_new = b[0] then c[0], then b[1] and then c[1], and so on if a is big
so do [0::2] ([ 0 1 2 3],[ 8 9 10 11]...] and [1::2] manipulate the data (can change rows and columns around if needed so with [0::2] you know you only want 0 and 2 with [1::2] you only want 1 and 3)..so get rid of stuff not using then can stack or concat and reshape if required...but I think @Paul Panzer answer is probably better
..so if you understand slicing and want to keep to that you can do above to get your [ 0 1 2 3],[ 8 9 10 11] etc then flatten slice again every other one to get 0,2,8,10... and reshape
do that with the second array [ 4 5 6 7],[12 13 14 15].. gives you two arrays which you have reshaped to be [0,2],[8,10].. and [5,7],[13,15] then append one to the other and sort if required
0
b = a.take([0,2,5,7,8,10,13,15]).reshape(4,2)
print(b)

array([[ 0,  2],
       [ 5,  7],
       [ 8, 10],
       [13, 15]])

2 Comments

Works well in this case, but my matrix a was just an example, I work with a 5494x3666 image, so... :P
well, the numbers are also the exact indexes of your array, so what you can do is generate those indexes numbers in a separate function, then use the resulting list as np.array.take() argument.

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.