Just doing d3 = array([d1,d2]) seems to work for me:
>>> from numpy import array
>>> # ... create d1 and d2 ...
>>> d1.shape
(18,18)
>>> d2.shape
(18,18)
>>> d3 = array([d1, d2])
>>> d3.shape
(2, 18, 18)
Answer from Daniel G on Stack OverflowJust doing d3 = array([d1,d2]) seems to work for me:
>>> from numpy import array
>>> # ... create d1 and d2 ...
>>> d1.shape
(18,18)
>>> d2.shape
(18,18)
>>> d3 = array([d1, d2])
>>> d3.shape
(2, 18, 18)
hstack and vstack do no change the number of dimensions of the arrays: they merely put them "side by side". Thus, combining 2-dimensional arrays creates a new 2-dimensional array (not a 3D one!).
You can do what Daniel suggested (directly use numpy.array([d1, d2])).
You can alternatively convert your arrays to 3D arrays before stacking them, by adding a new dimension to each array:
d3 = numpy.vstack([ d1[newaxis,...], d2[newaxis,...] ]) # shape = (2, 18, 18)
In fact, d1[newaxis,...].shape == (1, 18, 18), and you can stack both 3D arrays directly and get the new 3D array (d3) that you wanted.
If you know all of your 2D arrays at the start, you can just stack more than two of them:
import numpy as np
a = np.zeros((3, 4))
b = np.zeros((3, 4))
c = np.stack((a, b, a))
If you already have one "stacked" array and want to add another array to it, you can use e.g. numpy.concatenate:
If the array you want to add is "flat", you would have to wrap it in a list to make the dimensions match. By default, the arrays are joined along the first dimension (same as if you were to specify axis=0 in the keyword arguments):
>>> c.shape
(2, 3, 4)
>>> np.array([a]).shape
(1, 3, 4)
c = np.concatenate((c, [a]))
If both arrays are already "stacked", this will also work:
c = np.concatenate((c, c))
You can add a new axis with None/np.newaxis at the start of the array to be appended : a[None,:,:] or simply a[None,...] or just a[None] and for stacking use np.vstack.
Here's a sample run to make things clear -
In [14]: c.shape
Out[14]: (2, 3, 4)
In [15]: d = np.vstack((c,a[None]))
In [16]: d.shape
Out[16]: (3, 3, 4)
In [17]: e = np.vstack((d,a[None]))
In [18]: e.shape
Out[18]: (4, 3, 4)
Workflow
So, the workflow would be :
1) To start off with 2D arrays, use new axes for the arrays :
c = np.vstack( (a[None],b[None]) )
2) For later appending steps, use new axis for the incoming 2D array and use np.vstack to stack with the existing 3D array -
d = np.vstack((c,a[None]))
Using np.concatenate for performance :
np.vstack under the hoods uses np.concatenate as a special case when we need to stack along the first axis. So, if we want to make use of np.concatenate maybe for performance reasons to avoid the additional function call overhead, we need to specify the axis of concatenation, which would be the first axis.
Thus, with np.concatenate -
In [23]: d = np.concatenate((c, a[None]), axis=0)
In [24]: d.shape
Out[24]: (3, 3, 4)
In [25]: e = np.concatenate((d, a[None]), axis=0)
In [26]: e.shape
Out[26]: (4, 3, 4)
There are many ways how to construct multidimensional arrays.
If you want to construct a 3D array from given 2D arrays you can do something like
import numpy
# just some 2D arrays with shape (10,20)
a1 = numpy.ones((10,20))
a2 = 2* numpy.ones((10,20))
a3 = 3* numpy.ones((10,20))
# creating 3D array with shape (3,10,20)
b = numpy.array((a1,a2,a3))
Depending on the situation there are other ways which are faster. However, as long as you use built-in constructors instead of loops you are on the fast side.
For your concrete example in Edit I would use numpy.tri
c = numpy.zeros((20,10,10))
c[:] = numpy.tri(10,10,-1) - numpy.tri(10,10,-2)
Came across similar problem...
I needed to modify 2D array into 3D array like so:
(y, x) -> (y, x, 3).
Here is couple solutions for this problem.
Solution 1
Using python tool set
array_3d = numpy.zeros(list(array_2d.shape) + [3], 'f')
for z in range(3):
array_3d[:, :, z] = array_2d.copy()
Solution 2
Using numpy tool set
array_3d = numpy.stack([array_2d.copy(), ]*3, axis=2)
That is what I came up with. If someone knows numpy to give a better solution I would love to see it! This works but I suspect there is a better way performance-wise.
One can use np.tile. Before doing this, a dimension needs to be added at the end of the array.
In [28]: x = np.array([[ 1, 2, 3],
...: [ 4, 5, 6],
...: [ 7, 8, 9]])
In [29]: np.tile(x[..., None], 3)
Out[29]:
array([[[1, 1, 1],
[2, 2, 2],
[3, 3, 3]],
[[4, 4, 4],
[5, 5, 5],
[6, 6, 6]],
[[7, 7, 7],
[8, 8, 8],
[9, 9, 9]]])
First extend the dimension of 2D array using arr[:, :, np.newaxis], this changes dimension from (3, 3) to (3, 3, 1). Now repeat this 3D array along the third dimension.
Use:
arr = np.repeat(arr[:, :, np.newaxis], 3, -1)
Output:
>>> np.repeat(arr[:, :, np.newaxis], 3, -1)
array([[[1, 1, 1],
[2, 2, 2],
[3, 3, 3]],
[[4, 4, 4],
[5, 5, 5],
[6, 6, 6]],
[[7, 7, 7],
[8, 8, 8],
[9, 9, 9]]])
You need to use
data.reshape((data.shape[0], data.shape[1], 1))
Example
from numpy import array
data = [[11, 22],
[33, 44],
[55, 66]]
data = array(data)
print(data.shape)
data = data.reshape((data.shape[0], data.shape[1], 1))
print(data.shape)
Running the example first prints the size of each dimension in the 2D array, reshapes the array, then summarizes the shape of the new 3D array.
Result
(3,2)
(3,2,1)
Source :https://machinelearningmastery.com/index-slice-reshape-numpy-arrays-machine-learning-python/
If you want to create a 3D Matrix where every subarray is in the new 3D dimension, wouldn't the final shape be (350,9,5)? In that case, you can simply use:
new_array = np.asarray(data).reshape(350,9,5)