Python 如何向 Numpy 数组添加新维度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17394882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 08:06:31  来源:igfitidea点击:

How can I add new dimensions to a Numpy array?

pythonarraysopencvnumpy

提问by Chris

I'm starting off with a numpy array of an image.

我从一个图像的 numpy 数组开始。

In[1]:img = cv2.imread('test.jpg')

The shape is what you might expect for a 640x480 RGB image.

形状是您可能对 640x480 RGB 图像所期望的形状。

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.shapereturns (480, 640, 3, 100).

但是,我拥有的这张图像是视频的一帧,长度为 100 帧。理想情况下,我希望有一个包含此视频中所有数据的数组,以便img.shape返回(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?

将下一帧(即下一组图像数据,另一个 480 x 640 x 3 阵列)添加到我的初始阵列的最佳方法是什么?

回答by JoshAdel

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).

如果帧是以某种特定方式命名的单个 jpg 文件(在示例中,frame_0.jpg、frame_1.jpg 等)。

Just a note, you might consider using a (nframes, 480,640,3)shaped array, instead.

请注意,您可能会考虑使用(nframes, 480,640,3)成形数组。

回答by Saullo G. P. Castro

You can use np.concatenate()specifying which axisto append, using np.newaxis:

您可以使用np.concatenate()指定axis要附加的内容,使用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)

回答by dbliss

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:

您问的是如何向 NumPy 数组添加维度,以便随后可以增加该维度以容纳新数据。可以按如下方式添加维度:

image = image[..., np.newaxis]

回答by richar8086

I followed this approach:

我遵循了这种方法:

import numpy as np
import cv2

ls = []

for image in image_paths:
    ls.append(cv2.imread('test.jpg'))

img_np = np.array(ls) # shape (100, 480, 640, 3)
img_np = np.rollaxis(img_np, 0, 4) # shape (480, 640, 3, 100).

回答by Cleb

Alternatively to

或者

image = image[..., np.newaxis]

in @dbliss' answer, you can also use numpy.expand_dimslike

@dbliss 的回答中,你也可以使用numpy.expand_dims

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)

回答by Multihunter

There is no structure in numpy that allows you to append more data later.

numpy 中没有允许您稍后附加更多数据的结构。

Instead, numpy puts all of your data into a contiguous chunk of numbers (basically; a C array), and any resize requires allocating a new chunk of memory to hold it. Numpy's speed comes from being able to keep all the data in a numpy array in the same chunk of memory; e.g. mathematical operations can be parallelized for speedand you get less cache misses.

相反,numpy 将您的所有数据放入一个连续的数字块(基本上是一个 C 数组)中,并且任何调整大小都需要分配一个新的内存块来保存它。Numpy 的速度来自于能够将 numpy 数组中的所有数据保存在同一块内存中;例如,数学运算可以并行化以提高速度,从而减少缓存未命中

So you will have two kinds of solutions:

因此,您将有两种解决方案:

  1. Pre-allocate the memory for the numpy array and fill in the values, like in JoshAdel's answer, or
  2. Keep your data in a normal python list until it's actually needed to put them all together (see below)
  1. 为 numpy 数组预先分配内存并填写值,如 JoshAdel 的回答,或
  2. 将您的数据保存在一个普通的 Python 列表中,直到真正需要将它们放在一起(见下文)


images = []
for i in range(100):
    new_image = # pull image from somewhere
    images.append(new_image)
images = np.stack(images, axis=3)


Note that there is no need to expand the dimensions of the individual image arrays first, nor do you need to know how many images you expect ahead of time.

请注意,无需先扩展单个图像数组的维度,也无需提前知道期望的图像数量。

回答by Roman

Consider Approach 1 with reshape method and Approach 2 with np.newaxis method that produce the same outcome:

考虑使用 reshape 方法的方法 1 和使用 np.newaxis 方法的方法 2 产生相同的结果:

#Lets suppose, we have:
x = [1,2,3,4,5,6,7,8,9]
print('I. x',x)

xNpArr = np.array(x)
print('II. xNpArr',xNpArr)
print('III. xNpArr', xNpArr.shape)

xNpArr_3x3 = xNpArr.reshape((3,3))
print('IV. xNpArr_3x3.shape', xNpArr_3x3.shape)
print('V. xNpArr_3x3', xNpArr_3x3)

#Approach 1 with reshape method
xNpArrRs_1x3x3x1 = xNpArr_3x3.reshape((1,3,3,1))
print('VI. xNpArrRs_1x3x3x1.shape', xNpArrRs_1x3x3x1.shape)
print('VII. xNpArrRs_1x3x3x1', xNpArrRs_1x3x3x1)

#Approach 2 with np.newaxis method
xNpArrNa_1x3x3x1 = xNpArr_3x3[np.newaxis, ..., np.newaxis]
print('VIII. xNpArrNa_1x3x3x1.shape', xNpArrNa_1x3x3x1.shape)
print('IX. xNpArrNa_1x3x3x1', xNpArrNa_1x3x3x1)

We have as outcome:

我们的结果是:

I. x [1, 2, 3, 4, 5, 6, 7, 8, 9]

II. xNpArr [1 2 3 4 5 6 7 8 9]

III. xNpArr (9,)

IV. xNpArr_3x3.shape (3, 3)

V. xNpArr_3x3 [[1 2 3]
 [4 5 6]
 [7 8 9]]

VI. xNpArrRs_1x3x3x1.shape (1, 3, 3, 1)

VII. xNpArrRs_1x3x3x1 [[[[1]
   [2]
   [3]]

  [[4]
   [5]
   [6]]

  [[7]
   [8]
   [9]]]]

VIII. xNpArrNa_1x3x3x1.shape (1, 3, 3, 1)

IX. xNpArrNa_1x3x3x1 [[[[1]
   [2]
   [3]]

  [[4]
   [5]
   [6]]

  [[7]
   [8]
   [9]]]]

回答by 0-_-0

Pythonic

蟒蛇式

X = X[:, :, None]

X = X[:, :, None]

which is equivalent to

这相当于

X = X[:, :, numpy.newaxis]and X = numpy.expand_dims(X, axis=-1)

X = X[:, :, numpy.newaxis]X = numpy.expand_dims(X, axis=-1)

But as you are explicitly asking about stacking images, I would recommend going for stacking the listof images np.stack([X1, X2, X3])that you may have collected in a loop.

但是,当您明确询问堆叠图像时,我建议您将可能收集到list的图像np.stack([X1, X2, X3])进行循环堆叠。

If you do not like the order of the dimensions you can rearrange with np.transpose()

如果您不喜欢尺寸的顺序,您可以重新排列 np.transpose()