2016-07-15 126 views
7

我想知道爲什麼在numpy中有維度(長度,1)的一維數組,還有一維維度數組(長度, )沒有第二個值。numpy:爲什麼在(x,1)和(x,)維度之間存在差異

我經常遇到這種情況,例如,當使用np.concatenate()然後需要預先reshape步驟(或者我可以直接使用hstack/vstack)。

我想不出爲什麼這種行爲是可取的理由。有人可以解釋嗎?

編輯:
有人建議通過評論我的問題是一個可能的重複。我對Numpy的底層工作更感興趣,而不是認爲1d和2d數組有區別,我認爲這是所提到的線程的要點。

+1

'(x,)'是指向量,而不是矩陣。 – kennytm

+2

NumPy是圍繞n維數組構建的,而不是矩陣。 – user2357112

+0

@kennytm感謝您的輸入,但是向量不會被表示爲'(x,1)'的原因是什麼? – Dahlai

回答

9

ndarray的數據存儲爲1d緩衝區 - 只是一塊內存。數組的多維性質由shapestrides屬性以及使用它們的代碼生成。

numpy開發人員選擇,以允許尺寸的任意數量的,所以形狀和進展被表示爲任何長度的元組,包括0和1。

相反MATLAB是圍繞而開發的FORTRAN程序建用於矩陣運算。在早期,MATLAB中的所有東西都是2d矩陣。大約在2000年(v3.5),它被推廣到允許超過2d,但從不少於。 numpynp.matrix仍然遵循舊的2d MATLAB約束。

如果你來自MATLAB世界,你習慣了這兩個維度,以及行向量和列向量之間的區別。但是在不受MATLAB影響的數學和物理學中,矢量是一維數組。 Python列表本質上是1d,與c數組一樣。爲了得到2d,你必須有列表或指向數組的指針數組,並且使用x[1][2]樣式的索引。

看的形​​狀和該陣列的進步及其變體:

In [48]: x=np.arange(10) 

In [49]: x.shape 
Out[49]: (10,) 

In [50]: x.strides 
Out[50]: (4,) 

In [51]: x1=x.reshape(10,1) 

In [52]: x1.shape 
Out[52]: (10, 1) 

In [53]: x1.strides 
Out[53]: (4, 4) 

In [54]: x2=np.concatenate((x1,x1),axis=1) 

In [55]: x2.shape 
Out[55]: (10, 2) 

In [56]: x2.strides 
Out[56]: (8, 4) 

MATLAB在端部增加了新的尺寸。它命令它的值如order='F'數組,並且可以容易地將(n,1)矩陣改變爲(n,1,1,1)。 numpy默認爲order='C',並且在開始時很容易擴展數組維度。在充分利用廣播時,瞭解這一點至關重要。

因此x1 + x爲(10,1)+(10,)=>(10,1)+(1,10)=>(10,10)

由於廣播的(n,)陣列更像(1,n)一個比一個(n,1)之一。一維數組更像是一個行矩陣而不是一列數組。

In [64]: np.matrix(x) 
Out[64]: matrix([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]) 

In [65]: _.shape 
Out[65]: (1, 10) 

concatenate點是它需要匹配的尺寸。它不使用廣播來調整尺寸。有許多功能可以緩解這種限制,但是他們在使用concatenate之前通過調整尺寸來實現。看看他們的代碼(可讀的Python)。

因此,一個熟練numpy的用戶需要的舒適與廣義shape元組,包括空()(0D陣列)(n,) 1D和向上。對於更高級的東西,理解大步也很有幫助(例如,看一下轉置的步幅和形狀)。

+0

謝謝這對理解Numpy的起源非常有用行爲。我想知道現在這些1維數組的好處是什麼。他們爲什麼不隱藏在引擎蓋下,對用戶來說,一切都是最小的'(x,1)'數組?是否有'(x,)'數組有優勢的特定情況? – Dahlai

+0

'(x,1)'顯示爲一列。一個'(1,x)'作爲一行,但有一組額外的[]。我一直生成1d陣列,例如'np.arange(10)'。我可能會把它重塑成'(5,2)'。只有當我需要廣播它時,我纔會添加末尾的','[:,None]'。 – hpaulj

+0

我們可以說'(x,)'是一個Vector,其中'(x,1)'是一個矩陣? – weima

2

其中大部分是語法問題。這個元組(x)根本不是元組(只是冗餘)。然而,(x,)是。

(x,)和(x,1)之間的區別更進一步。你可以看看以前的問題的例子,如this。從它引用的例子,這是一個一維數組numpy的:

>>> np.array([1, 2, 3]).shape 
(3,) 

但是這一次是2D:

>>> np.array([[1, 2, 3]]).shape 
(1, 3) 

Reshape does not make a copy unless it needs to所以它應該是安全的使用。

相關問題