Accessing individual columns in a numpy ndarray

Viewed 125

I have an nd-numpy array of shape (m, 1,100,4) for which I would like to access the individual columns of the inner array (shape: (1,100,4)).

MWE: As example, say I have this:

import numpy as np
X = np.random.randn(2, 1, 5, 4)
    
X
array([[[[-0.40867508,  0.09331783,  1.26134307, -1.18900601],
         [-0.79177772,  0.96738931, -0.33332772,  0.53130287],
         [ 3.67290383,  0.30954936,  0.63221306, -0.64003826],
         [-1.20878773,  1.21499506,  1.84995811,  0.15663168],
         [-0.60648072, -0.30464852, -0.44044224, -4.46482868]]],


       [[[-1.90531392, -0.47108517,  1.21177166,  0.09561669],
         [ 3.21803694,  0.30611821,  1.71334417,  0.73383279],
         [-1.12869017, -0.1497266 , -0.54913676,  0.36704922],
         [ 0.5652546 , -0.75012341, -0.72496611,  1.12428097],
         [-1.19727408, -0.13813127,  2.63948821, -0.37661527]]]])

where nested arrays are shaped (1,5,4). Then accessing the first columns of each nested array returns the entire array instead:

X[ :, 0]
array([[[-0.40867508,  0.09331783,  1.26134307, -1.18900601],
        [-0.79177772,  0.96738931, -0.33332772,  0.53130287],
        [ 3.67290383,  0.30954936,  0.63221306, -0.64003826],
        [-1.20878773,  1.21499506,  1.84995811,  0.15663168],
        [-0.60648072, -0.30464852, -0.44044224, -4.46482868]],

       [[-1.90531392, -0.47108517,  1.21177166,  0.09561669],
        [ 3.21803694,  0.30611821,  1.71334417,  0.73383279],
        [-1.12869017, -0.1497266 , -0.54913676,  0.36704922],
        [ 0.5652546 , -0.75012341, -0.72496611,  1.12428097],
        [-1.19727408, -0.13813127,  2.63948821, -0.37661527]]])

My intention is to get a tuple, such that:

s,t,u,v = X[first_columns], X[second_columns], X[third_columns], X[fouth_columns]

such that:

s =[-0.40867508, -0.79177772, 3.67290383, -1.20878773, -0.60648072,
   -1.90531392, 3.21803694, -1.12869017, 0.5652546, -1.19727408]
4 Answers

What you are looking for is

X[:,0,:,0].ravel()

Note that with this shape of X, we cannot directly get the desired elements as an array but as a 2d matrix. Therefore we need to reshape to array form.

The other correspond to:

t = X[:,0,:,1].ravel()
u = X[:,0,:,2].ravel()
v = X[:,0,:,3].ravel()

If you reshape the array into the the appropriate way, you can directly unpack its inner arrays into s,t,u,v. In this case we can transpose and swapaxes to bring the columns to the front, then squeeze to remove that additional single axis:

s,t,u,v = X.T.swapaxes(1,3).squeeze()

print(s)
array([[-0.40867508, -0.79177772,  3.67290383, -1.20878773, -0.60648072],
       [-1.90531392,  3.21803694, -1.12869017,  0.5652546 , -1.19727408]])

print(t)
array([[ 0.09331783,  0.96738931,  0.30954936,  1.21499506, -0.30464852],
       [-0.47108517,  0.30611821, -0.1497266 , -0.75012341, -0.13813127]])

I would just access the array like this: X[0,0,:].T, or using a loop to cover the entire first dimension:

for i in range(X.shape[0]):
    a,b,c,d = X[i,0,:].T

Explanation: by setting the 1st and 2nd dimensions (1st to i, 2nd to 0 due to its size 1), you get a 2D array. To extract the columns, just apply transpose or .T and get each column separately.

E.g.:

X = np.random.randn(2, 1, 5, 4)
X
array([[[[-0.5654864 ,  0.83400636, -0.43981782,  0.79797726],
         [-0.53889591,  0.20837148, -0.14120152,  1.4920727 ],
         [ 0.45982834,  0.18474384, -1.47445088, -1.10874298],
         [-1.45259119, -1.72788464, -0.19379806, -0.42558103],
         [-2.16298358,  0.10093486, -0.00730153,  0.00871548]]],

       [[[ 0.60556812, -0.55684663, -0.63648966, -0.34645153],
         [ 0.39557121,  1.50672188, -1.06762611, -1.38979522],
         [-0.06393524, -0.84720836,  0.27615171, -0.31991015],
         [-0.9626267 ,  0.26539901, -1.08703265, -0.97718657],
         [-0.39556868, -0.81102407,  0.33091579, -0.652497  ]]]])

a,b,c,d = X[0,0,:].T
a,b,c,d
(array([-0.5654864 , -0.53889591,  0.45982834, -1.45259119, -2.16298358]),
 array([ 0.83400636,  0.20837148,  0.18474384, -1.72788464,  0.10093486]),
 array([-0.43981782, -0.14120152, -1.47445088, -0.19379806, -0.00730153]),
 array([ 0.79797726,  1.4920727 , -1.10874298, -0.42558103,  0.00871548]))

If you want to get all columns at once, just reshape your data from [a,1,b,c] to [1,a*b,c] and transpose:

a,b,c,d = X.reshape([1,10,4]).T
Related