Suppose I have four (N,) vectors A, B, C, and D:
import numpy as np
N = 100
A = 1*np.ones(N) # => array([1,1,1,...])
B = 2*np.ones(N) # => array([2,2,2,...])
C = 3*np.ones(N) # => array([3,3,3,...])
D = 4*np.ones(N) # => array([4,4,4,...])
In my application, these are each an element of a matrix and the matrix varies over time (although in this example each is constant in time). I want a matrix with shape (N,2,2) such that I have a 2×2 matrix for each time step, like [[a,b],[c,d]], extended along axis 0. Is there a nicer way to stack these into that kind of shape than what I have below?
My solution:
A_ = np.reshape(A, (N,1,1))
B_ = np.reshape(B, (N,1,1))
C_ = np.reshape(C, (N,1,1))
D_ = np.reshape(D, (N,1,1))
AB = np.concatenate((A_, B_),axis=2)
CD = np.concatenate((C_, D_),axis=2)
ABCD = np.concatenate((AB,CD),axis=1)
This gives:
>>> ABCD
array([[[1., 2.],
[3., 4.]],
[[1., 2.],
[3., 4.]],
[[1., 2.],
[3., 4.]],
...
...
[[1., 2.],
[3., 4.]],
[[1., 2.],
[3., 4.]]])
As desired. It’s just difficult to understand what it’s doing, so I’m wondering if there’s a better way.
>Solution :
Concatenate as a 3D intermediate with dstack, then you’ll be in the ideal order to perform a simple reshape:
np.dstack([A, B, C, D]).reshape(N, 2, 2)
Output:
array([[[1., 2.],
[3., 4.]],
[[1., 2.],
[3., 4.]],
[[1., 2.],
[3., 4.]],
...,
[[3., 4.],
[3., 4.]]])
Intermediate:
np.dstack([A,B,C,D]).shape
# (1, 100, 4)