2

I've been trying to do something like a numpy.array_split(), but to split it like this instead:

enter image description here So It would return an array (for example let's call it output[] ) with n 2D subarrays inside of it.

For example (for n = 3):

  • output[0] would return the (yellow) subarray with columns a1, a4, a7, a10,
  • output[1] would return the (red) subarray with columns a2, a5, a8,
  • output[2] would return the (blue) subarray with columns a3, a6, a9.
def split(arr, n):
    output= [[] for _ in range(n)]
    for v, help in zip(arr, cycle(out)):
        help.append(v)
    return output

I don't know how to combine rows into one 2D array, so I have many 1D arrays instead of one 2D.

2
  • I don't know how to combine rows into one 2D array, so I have many 1D arrays instead of one 2D. Commented Aug 29, 2022 at 12:09
  • edit your question and post your code (properly formatted as code) Commented Aug 29, 2022 at 12:09

3 Answers 3

2

Not sure if a native solution exists but you can use:

# get groups
group = np.arange(a.shape[1])%n
# groups sorting order
order = np.argsort(group)
# get counts of each group (in order as the output is sorted)
_, idx = np.unique(group, return_counts=True)
# split the reindexed array
out = np.split(a[:, order], np.cumsum(idx[:-1]), axis=1)

Output:

[array([[ 0,  3,  6,  9],
        [10, 13, 16, 19],
        [20, 23, 26, 29],
        [30, 33, 36, 39],
        [40, 43, 46, 49]]),
 array([[ 1,  4,  7],
        [11, 14, 17],
        [21, 24, 27],
        [31, 34, 37],
        [41, 44, 47]]),
 array([[ 2,  5,  8],
        [12, 15, 18],
        [22, 25, 28],
        [32, 35, 38],
        [42, 45, 48]])]

Used input:

array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]])
Sign up to request clarification or add additional context in comments.

Comments

1

You can use slicing [start:end:step] in numpy.array. (understanding-slicing)

n = 3
m = inp.shape[1] // n
output = [inp[:, i::3] for i in range(m)]

Example

import numpy as np

inp = np.arange(50).reshape(5, 10)

n = 3
m = inp.shape[1] // n
output = [inp[:, i::3] for i in range(m)]
print(output)

# [
#     array([[ 0,  3,  6,  9],     [0::3] -> columns : 0, 3, 6, 9
#            [10, 13, 16, 19],
#            [20, 23, 26, 29],
#            [30, 33, 36, 39],
#            [40, 43, 46, 49]]), 
 
#     array([[ 1,  4,  7],         [1::3] -> columns : 1, 4, 7
#            [11, 14, 17],
#            [21, 24, 27],
#            [31, 34, 37],
#            [41, 44, 47]]), 
    
#     array([[ 2,  5,  8],         [2::3] -> columns : 2, 5, 8
#            [12, 15, 18],
#            [22, 25, 28],
#            [32, 35, 38],
#            [42, 45, 48]])
# ]

Input array:

#column: 0,  1,  2,  3,  4,  5,  6,  7,  8,  9

array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
       [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]])

Comments

1

Another possible solution, based on map:

n = 3
_, ncols = m.shape
out = list(map(lambda x: m[:, np.arange(0, ncols)[x::n]], np.arange(0,n)))
out

Output:

[array([[0, 4, 3, 6],
       [6, 8, 1, 9],
       [3, 5, 4, 1],
       [0, 0, 8, 0],
       [0, 8, 7, 4]]), 
 array([[7, 4, 5],
       [2, 9, 6],
       [2, 3, 5],
       [1, 6, 8],
       [8, 2, 2]]), 
 array([[4, 4, 5],
       [8, 5, 2],
       [7, 8, 4],
       [4, 8, 3],
       [0, 2, 6]])]

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.