2017-03-02 113 views
1

我碰到這行代碼,使用numpy的Python - numpy的重塑

img = data.reshape(data.shape[0], 3, 32, 32) 

我明白了這行代碼,除了data.shape[0]。我知道的是,這部分將返回行數。但是,我沒有得到的是data(即行)將如何被重塑爲matrix 3-channels。爲什麼沒有單獨使用data

也許我在這裏混淆的東西?

謝謝。

+0

再次閱讀文檔可能會有幫助。 – Divakar

+0

'data'的形狀是什麼?它必須至少是2d,並且'data.shape [1:]'值與3 * 32 * 32具有相同的產品。 – hpaulj

回答

1

這樣做有道理的一種方法是,如果你確切地知道最終的結果是多少維度,但你不知道有多少行;例如,

In [9]: data.shape 
Out[9]: (5, 3072) 

In [7]: img = data.reshape(data.shape[0], 3, 32, 32) # 3072 = 3*32*32 

In [10]: img.shape 
Out[10]: (5, 3, 32, 32) 
2

當重塑一個矩陣時,新形狀應該與原始形狀兼容。

爲了動態確保這一點,此代碼使用data.shape [0]來獲得原始矩陣的行數(即第一維data)。知道這一點,它將矩陣重塑爲一個4d矩陣,定義如下:rows | 3 | 32 | 32。

正如您所指出的那樣,數組本身可能已經被使用,所以這段代碼並沒有檢查行數的有效性,而是使用了行計數來確保行元素不會混洗到新列中在重塑期間。

1

假設你有一個包含N行的數組,每行是一個3 * 32 * 32 = 3072長陣列。如果您不確定有多少條線,但知道您希望其餘的線重新成形爲(3, 32, 32),則可以使用指示的線。

否則,你會得到一個錯誤:

>>> import numpy as np 
>>> n_lines = 10 
>>> data = np.arange(n_lines*3*32*32) 
>>> data.reshape(n_lines + 1 , 3*32*32) # notice the + 1 !! 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: total size of new array must be unchanged 

但是如果你使用正確的數字:

>>> data.reshape(n_lines, 3*32*32) 
array([[ 0,  1,  2, ..., 3069, 3070, 3071], 
     [ 3072, 3073, 3074, ..., 6141, 6142, 6143], 
     [ 6144, 6145, 6146, ..., 9213, 9214, 9215], 
     ..., 
     [21504, 21505, 21506, ..., 24573, 24574, 24575], 
     [24576, 24577, 24578, ..., 27645, 27646, 27647], 
     [27648, 27649, 27650, ..., 30717, 30718, 30719]]) 
>>> data.reshape(n_lines, 3, 32, 32) 
array([[[[ 0,  1,  2, ..., 29, 30, 31], 
     [ 32, 33, 34, ..., 61, 62, 63], 
     [ 64, 65, 66, ..., 93, 94, 95], 
     ..., 
     [ 928, 929, 930, ..., 957, 958, 959], 
     [ 960, 961, 962, ..., 989, 990, 991], 
     [ 992, 993, 994, ..., 1021, 1022, 1023]], 

     [[ 1024, 1025, 1026, ..., 
1

重塑不能改變數據的大小,但它可以改變的維數。如果原始形狀是例如(10x3072)(10x3x1024)您可以將整個陣列重塑爲10x3x32x32而不是9x3x32x32

顯然,這段代碼是爲了保持第一個維度不變並重新整形數組的其餘部分而編寫的。無論data的實際形狀是什麼,如果data的尺寸是N * 3072,img將始終爲Nx3x32x32。否則這會引發錯誤。

大概誰寫的代碼不知道,你可以以自動設置一個維度的大小通過-1reshape

img = data.reshape(-1, 3, 32, 32) 

這是可能的,因爲數據的總大小必須保持不變。

Why didn't data alone be used?

很難說在不知道數據的前面形狀,但是從名字img我會扣除重整的陣列很可能應該持有的n 32x32的RGB圖像的集合。