How can I add new dimensions to a Numpy array?
Solution 1
You're asking how to add a dimension to a NumPy array, so that that dimension can then be grown to accommodate new data. A dimension can be added as follows:
image = image[..., np.newaxis]
Solution 2
Alternatively to
image = image[..., np.newaxis]
in @dbliss' answer, you can also use numpy.expand_dims
like
image = np.expand_dims(image, <your desired dimension>)
For example (taken from the link above):
x = np.array([1, 2])
print(x.shape) # prints (2,)
Then
y = np.expand_dims(x, axis=0)
yields
array([[1, 2]])
and
y.shape
gives
(1, 2)
Solution 3
You could just create an array of the correct size up-front and fill it:
frames = np.empty((480, 640, 3, 100))
for k in xrange(nframes):
frames[:,:,:,k] = cv2.imread('frame_{}.jpg'.format(k))
if the frames were individual jpg file that were named in some particular way (in the example, frame_0.jpg, frame_1.jpg, etc).
Just a note, you might consider using a (nframes, 480,640,3)
shaped array, instead.
Solution 4
Pythonic
X = X[:, :, None]
which is equivalent to
X = X[:, :, numpy.newaxis]
and
X = numpy.expand_dims(X, axis=-1)
But as you are explicitly asking about stacking images,
I would recommend going for stacking the list
of images np.stack([X1, X2, X3])
that you may have collected in a loop.
If you do not like the order of the dimensions you can rearrange with np.transpose()
Solution 5
You can use np.concatenate()
specifying which axis
to append, using np.newaxis
:
import numpy as np
movie = np.concatenate((img1[:,np.newaxis], img2[:,np.newaxis]), axis=3)
If you are reading from many files:
import glob
movie = np.concatenate([cv2.imread(p)[:,np.newaxis] for p in glob.glob('*.jpg')], axis=3)
Chris
Updated on July 08, 2022Comments
-
Chris almost 2 years
I'm starting off with a numpy array of an image.
In[1]:img = cv2.imread('test.jpg')
The shape is what you might expect for a 640x480 RGB image.
In[2]:img.shape Out[2]: (480, 640, 3)
However, this image that I have is a frame of a video, which is 100 frames long. Ideally, I would like to have a single array that contains all the data from this video such that
img.shape
returns(480, 640, 3, 100)
.What is the best way to add the next frame -- that is, the next set of image data, another 480 x 640 x 3 array -- to my initial array?
-
Magellan88 about 10 yearsI think this is the way to go. if you use the concatenation you will need to move the array in memory every time you add to it. for 100 frames that should not matter at all, but if you want to go to larger videos. BTW, I would have used the number of frames as the first dimension so have a (100,480,640,3) array that way you can access individual frames (what is usually want you will want to look at, right?) easier (F[1] instead of F[:,:,:,1]). Of course performance wise it should not matter at all.
-
Ray about 8 yearsCurrently,
numpy.newaxis
is defined to beNone
(in filenumeric.py
), so equivalently you could use `image = image[..., None]. -
weima almost 7 yearshow to add values in the new dimention? if i do
y[1,0]
it gives index out of bounds error.y[0,1]
is accessible -
Cleb almost 7 years@weima: Not fully sure what you are after. What is your desired output?
-
Neil G about 6 yearsDon't use
None
. Usenp.newaxis
because explicit is better than implicit. -
Pedro Rodrigues over 4 yearsHow can that be?
None
does not imply anything. It is explicit. It isNone
. Stated clearly.None
is a thing in python. There is no doubt.None
is the last detail, you cannot go deeper. On the other hand,numpy.newaxis
impliesNone
. It is, essentially,None
. It isNone
. But isNone
implicitly. It isNone
though not directly expressed asNone
. Explicit stated clearly and in detail, leaving no room for confusion or doubt. Implicit suggested though not directly expressed. I must add, that, from an API perspective, it is safer to usenumpy.newaxis
. -
Gabrer almost 4 yearsGuess here, being explicit refers to the "coder intent" rather than to the syntactical/semantical clarity.
-
Dan Boschen over 3 yearsJoshAdel's answer should be selected as the right answer in this case and needs more votes. His point is significant in that the OP is looking to add to the higher dimensioned nparray as he goes. ndarray's cannot be increased in size once created, a copy must be made. This answer will only make the shape (480, 640, 3, 1) and every time you add a new frame you will be making another copy. Not good.
-
Dan Boschen over 3 yearsI agree with JoshAdel and Magellan88, the other answers are very inefficient memory wise and processing time-- ndarrays cannot be increased in size once created, so a copy will always be made if you think you are appending to it.
-
chikitin about 3 yearswhere is the reference to this, please?
-
Kaniee about 3 yearsSince the title asks about adding (multiple) dimensions, I would like to add a way to add
n
dimensions:a[(..., *([np.newaxis] * n))]
. The parentheses constructing atuple
are necessary to unpack thelist
ofn
timesnp.newaxis
-
KansaiRobot over 2 yearsWhere is the value of "your desired dimension" go? I can see only the value 1