Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy: stack array by the last dimension

Suppose I have 3 numpy arrays a, b, c, of the same shape, say

a.shape == b.shape == c.shape == (7,9)

Now I'd like to create a 3-dimensional array of size (7,9,3), say x, such that

x[:,:,0] == a
x[:,:,1] == b
x[:,:,2] == c

What is the "pythonic" way of doing it (perhaps in one line)?

Thanks in advance!

like image 691
Ying Xiong Avatar asked Jan 04 '15 19:01

Ying Xiong


People also ask

How do you stack an array depth wise?

To stack masked arrays in sequence depth wise (along third axis), use the ma. dstack() method in Python Numpy. This is equivalent to concatenation along the third axis after 2-D arrays of shape (M,N) have been reshaped to (M,N,1) and 1-D arrays of shape (N,) have been reshaped to (1,N,1).

How do I stack NumPy arrays vertically?

vstack() function is used to stack the sequence of input arrays vertically to make a single array. Parameters : tup : [sequence of ndarrays] Tuple containing arrays to be stacked.

What is the difference between stack and concatenate?

stack() is used for joining multiple NumPy arrays. Unlike, concatenate(), it joins arrays along a new axis. It returns a NumPy array. to join 2 arrays, they must have the same shape and dimensions.

How do you stack 3 NumPy arrays?

numpy. dstack stack the array along the third axis, so, if you stack 3 arrays ( a , b , c ) of shape (N,M) , you'll end up with an array of shape (N,M,3) . That gives you a (3,N,M) array. Pierre, many thanks for your answer, I will test this option in my project.


2 Answers

There's a function that does exactly that: numpy.dstack ("d" for "depth"). For example:

In [10]: import numpy as np

In [11]: a = np.ones((7, 9))

In [12]: b = a * 2

In [13]: c = a * 3

In [15]: x = np.dstack((a, b, c))

In [16]: x.shape
Out[16]: (7, 9, 3)

In [17]: (x[:, :, 0] == a).all()
Out[17]: True

In [18]: (x[:, :, 1] == b).all()
Out[18]: True

In [19]: (x[:, :, 2] == c).all()
Out[19]: True
like image 62
NPE Avatar answered Oct 04 '22 22:10

NPE


TL;DR:

Use numpy.stack (docs), which joins a sequence of arrays along a new axis of your choice.


Although @NPE answer is very good and cover many cases, there are some scenarios in which numpy.dstack isn't the right choice (I've just found that out while trying to use it). That's because numpy.dstack, according to the docs:

Stacks arrays in sequence depth wise (along third axis).

This is equivalent to concatenation along the third axis after 2-D arrays of shape (M,N) have been reshaped to (M,N,1) and 1-D arrays of shape (N,) have been reshaped to (1,N,1).

Let's walk through an example in which this function isn't desirable. Suppose you have a list with 512 numpy arrays of shape (3, 3, 3) and want to stack them in order to get a new array of shape (3, 3, 3, 512). In my case, those 512 arrays were filters of a 2D-convolutional layer. If you use numpy.dstack:

>>> len(arrays_list)
512
>>> arrays_list[0].shape
(3, 3, 3)
>>> numpy.dstack(arrays_list).shape
(3, 3, 1536)

That's because numpy.dstack always stacks the arrays along the third axis! Alternatively, you should use numpy.stack (docs), which joins a sequence of arrays along a new axis of your choice:

>>> numpy.stack(arrays_list, axis=-1).shape
(3, 3, 3, 512)

In my case, I passed -1 to the axis parameter because I wanted the arrays stacked along the last axis.

like image 34
Talendar Avatar answered Oct 04 '22 22:10

Talendar