ttsesm
ttsesm

Reputation: 947

Numpy array - stack multiple columns at the end of an array as rows using reshape

I want to stack n number of columns as new rows at the end of the array. I was trying to do it with reshape but I couldn't make it. For example given the table

table = np.array([[11,12,13,14,15,16],
                  [21,22,23,24,25,26],
                  [31,32,33,34,35,36],
                  [41,42,43,44,45,46]])

my output if n=2 should be:

array([[11, 12], 
       [21, 22], 
       [31, 32], 
       [41, 42], 
       [13, 14], 
       [23, 24], 
       [33, 34], 
       [43, 44], 
       [15, 16], 
       [25, 26], 
       [35, 36], 
       [45, 46]])

and if n=3:

array([[11, 12, 13], 
       [21, 22, 23], 
       [31, 32, 33], 
       [41, 42, 43], 
       [14, 15, 16], 
       [24, 25. 26], 
       [34, 35, 36], 
       [44, 45, 46]])

Update:

Ok,I managed to achieve the result that I want with the following command:

import numpy as np

n=2
np.concatenate(np.split(table, table.shape[1]/n, axis=1), axis=0)
n=3
np.concatenate(np.split(table, table.shape[1]/n, axis=1), axis=0)

I do not know though if it is possible to be done with reshape.

Upvotes: 0

Views: 790

Answers (1)

mathfux
mathfux

Reputation: 5949

OP offers a solution:

np.concatenate(np.split(table, table.shape[1]/n, axis=1), axis=0)

It appears to be inefficient because np.split forces to change data to list of arrays and then iterate it within outer argument. More over np.concatenate is not that efficient as well. They are ideal to work when lengths of items of list are not balanced.

My solution is like so:

np.vstack(table.reshape(4,3,2).swapaxes(0,1))
#np.vstack(table.reshape(4,2,3).swapaxes(0,1)) #for second case

Let's check if my prediction of performance was correct:

%timeit np.vstack(table.reshape(4,3,2).swapaxes(0,1))
%timeit np.concatenate(np.split(table, table.shape[1]/2, axis=1), axis=0)

Output:

22.4 µs ± 2.72 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
42.8 µs ± 9.09 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

I was looking for solution with an assist of numpyviz (Disclaimer: I'm its author). There is a numpyvizualisation that helps to understand a process better:

enter image description here

In general you need to set a shape so that blocks preserves width and height. Numpyvizualisation hints that axis=0 and axis=2 of new shape corresponds to table.shape[0] and n respectively. Also the lenght of middle axis is a number of blocks which is table.shape[1]\\n. So you can pass arguments like so:

table.reshape(table.shape[0], table.shape[1]\\n, n)

or even in a more simple way:

table.reshape(table.shape[0], -1, n)

Upvotes: 2

Related Questions