簡體   English   中英

如何向 Numpy 數組添加新維度?

[英]How can I add new dimensions to a Numpy array?

我從 numpy 圖像數組開始。

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

該形狀是您對 640x480 RGB 圖像的期望。

In[2]:img.shape
Out[2]: (480, 640, 3)

但是,我擁有的這張圖片是視頻的一幀,長 100 幀。 理想情況下,我希望有一個包含該視頻中所有數據的數組,以便img.shape返回(480, 640, 3, 100)

將下一幀(即下一組圖像數據,另一個 480 x 640 x 3 陣列)添加到我的初始陣列的最佳方法是什么?

您正在詢問如何向 NumPy 數組添加維度,以便隨后可以增長該維度以容納新數據。 可以按如下方式添加維度:

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

或者

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

@dbliss 的答案中,您還可以使用numpy.expand_dims類的

image = np.expand_dims(image, <your desired dimension>)

例如(取自上面的鏈接):

x = np.array([1, 2])

print(x.shape)  # prints (2,)

然后

y = np.expand_dims(x, axis=0)

產量

array([[1, 2]])

y.shape

(1, 2)

您可以預先創建一個正確大小的數組並填充它:

frames = np.empty((480, 640, 3, 100))

for k in xrange(nframes):
    frames[:,:,:,k] = cv2.imread('frame_{}.jpg'.format(k))

如果幀是以某種特定方式命名的單個 jpg 文件(在示例中為 frame_0.jpg、frame_1.jpg 等)。

請注意,您可以考慮改用(nframes, 480,640,3)形狀的數組。

蟒蛇式

X = X[:, :, None]

這相當於

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

但是當您明確詢問堆疊圖像時,我建議您堆疊您可能在循環中收集的圖像list np.stack([X1, X2, X3])

如果您不喜歡尺寸的順序,您可以使用np.transpose()重新排列

您可以使用np.concatenate()指定要附加的axis ,使用np.newaxis

import numpy as np
movie = np.concatenate((img1[:,np.newaxis], img2[:,np.newaxis]), axis=3)

如果您正在讀取許多文件:

import glob
movie = np.concatenate([cv2.imread(p)[:,np.newaxis] for p in glob.glob('*.jpg')], axis=3)

考慮使用 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)

我們有結果:

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]]]]

numpy 中沒有允許您稍后附加更多數據的結構。

相反,numpy 將所有數據放入一個連續的數字塊中(基本上是一個 C 數組),並且任何調整大小都需要分配一個新的內存塊來保存它。 Numpy 的速度來自於能夠將 numpy 數組中的所有數據保存在同一塊內存中; 例如,數學運算可以並行化以提高速度,從而減少緩存未命中

所以你會有兩種解決方案:

  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)

請注意,無需先擴展單個圖像數組的維度,也無需提前知道預期的圖像數量。

a = np.expand_dims(a, axis=-1) 

或者

a = a[:, np.newaxis] 

或者

a = a.reshape(a.shape + (1,))

我遵循了這種方法:

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

這對我有用:

image = image[..., None]

您可以將堆棧與軸參數一起使用:

img.shape  # h,w,3
imgs = np.stack([img1,img2,img3,img4], axis=-1)   # -1 = new axis is last
imgs.shape #  h,w,3,nimages

例如:將灰度轉換為彩色:

>>> d = np.zeros((5,4), dtype=int)  # 5x4
>>> d[2,3] = 1

>>> d3.shape
Out[30]: (5, 4, 3)

>>> d3 = np.stack([d,d,d], axis=-2)  # 5x4x3   -1=as last axis
>>> d3[2,3]
Out[32]: array([1, 1, 1])

這將幫助您在所需的任何位置添加軸

    import numpy as np
    signal = np.array([[0.3394572666491664, 0.3089068053925853, 0.3516359279582483], [0.33932706934615525, 0.3094755563319447, 0.3511973743219001], [0.3394407172182317, 0.30889042266755573, 0.35166886011421256], [0.3394407172182317, 0.30889042266755573, 0.35166886011421256]])
    
    print(signal.shape)
#(4,3)
    print(signal[...,np.newaxis].shape)  or  signal[...:none]
#(4, 3, 1) 
    print(signal[:, np.newaxis, :].shape)  or signal[:,none, :]

#(4, 1, 3)

向 ndarray 添加新維度有三種方法。

首先:使用“np.newaxis”(類似於@dbliss 答案)

  • np.newaxis 只是給 None 一個別名,以便更容易
    理解。 如果你用 None 替換 np.newaxis,它的工作原理是一樣的
    方法。 但最好更明確地使用 np.newaxis 。
import numpy as np

my_arr = np.array([2, 3])
new_arr = my_arr[..., np.newaxis]

print("old shape", my_arr.shape)
print("new shape", new_arr.shape)

>>> old shape (2,)
>>> new shape (2, 1)

第二:使用“np.expand_dims()”

  • 在第一個參數和 position 中指定原始 ndarray 以在第二個參數軸中添加維度。
my_arr = np.array([2, 3])
new_arr = np.expand_dims(my_arr, -1)

print("old shape", my_arr.shape)
print("new shape", new_arr.shape)

>>> old shape (2,)
>>> new shape (2, 1)

第三:使用“reshape()”

my_arr = np.array([2, 3])
new_arr = my_arr.reshape(*my_arr.shape, 1)

print("old shape", my_arr.shape)
print("new shape", new_arr.shape)

>>> old shape (2,)
>>> new shape (2, 1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM