Numpy 修煉之道 (7)—— 形狀操作
Numpy 有一個強大之處在於可以很方便的修改生成的N維陣列的形狀。
更改陣列形狀
陣列具有由沿著每個軸的元素數量給出的形狀:
>>> a =np.floor(10*np.random.random((3,4)))
>>> a
array([[ 6., 7., 2., 0.],[ 6., 2.,0., 9.], [ 3., 9.,3., 8.]])
>>> a.shape
(3L, 4L)
上面生成了一個
3x4 的陣列,現在對它進行形狀的改變。
>>> a.ravel() # 進行平鋪
array([ 6., 7., 2., 0., 6., 2., 0.,9., 3., 9., 3., 8.])
>>> a.reshape(2, 6) # 重塑成 2x6
array([[ 6., 7., 2., 0., 6., 2.], [ 0., 9.,3., 9., 3., 8.]])
>>> a.T # 轉置
array([[ 6., 6., 3.], [ 7., 2.,9.], [ 2., 0.,3.],[ 0., 9.,8.]])
>>> a.shape
(3L, 4L)
無論是ravel、reshape、T,它們都不會更改原有的陣列形狀,都是返回一個新的陣列。
使用 resize 方法可以直接修改陣列本身:
>>> a
array([[ 6., 7., 2., 0.], [ 6., 2.,0., 9.],[ 3., 9.,3., 8.]])
>>> a.resize(2, 6)
>>> a
array([[ 6., 7., 2., 0., 6., 2.], [ 0., 9.,3., 9., 3., 8.]])
技巧:在使用 reshape 時,可以將其中的一個維度指定為 -1,Numpy 會自動計算出它的真實值
>>> a.reshape(3, -1)
array([[ 6., 7., 2., 0.],[ 6., 2.,0., 9.],[ 3., 9.,3., 8.]])
將不同陣列堆疊在一起
除了可以對單個數組的形狀進行轉換外,還可以把多個數據進行堆疊。
>>> a =np.floor(10*np.random.random((2,2)))
>>> a
array([[ 9., 9.], [ 8., 1.]])
>>> b = np.floor(10*np.random.random((2,2)))
>>> b
array([[ 5., 2.], [ 9., 5.]])
>>> np.vstack((a,b))
array([[ 9., 9.], [ 8., 1.],[ 5., 2.], [ 9., 5.]])
>>> np.hstack((a,b))
array([[ 9., 9., 5., 2.], [ 8., 1.,9., 5.]])
對於2D陣列來說,使用hstack和column_stack 效果一樣,對於1D陣列來說,column_stack 會將1D陣列作為列堆疊到2D陣列中:
>>> from numpy import newaxis
>>> np.column_stack((a,b)) # with 2D arrays
array([[ 4., 3.], [ 2., 8.]])
>>> a = np.array([4.,2.])
>>> b = np.array([3.,8.])
>>> np.column_stack((a,b))
array([[ 4., 3.],[ 2., 8.]])
>>> np.hstack((a,b)) # 一維陣列的情況下,column_stack和hstack結果不一樣
array([ 4., 2., 3., 8.])
>>> a[:,newaxis] # 將一維陣列轉為二維陣列
array([[ 4.], [ 2.]])
>>> np.column_stack((a[:,newaxis],b[:,newaxis]))
array([[ 4., 3.], [ 2., 8.]])
>>> np.hstack((a[:,newaxis],b[:,newaxis])) # 二維陣列的情況下,column_stack和hstack結果一樣
array([[ 4., 3.],[ 2., 8.]])
另一方面,對於任何輸入陣列,函式row_stack等效於vstack。一般來說,對於具有兩個以上維度的陣列,hstack沿第二軸堆疊,vstack沿第一軸堆疊,concatenate允許一個可選引數,給出串接應該發生的軸。
將一個數組分成幾個較小的陣列
既然可以將多個數組進行對堆疊,自然也可以將一個數組拆分成多個小陣列。
使用hsplit,可以沿其水平軸拆分陣列,通過指定要返回的均勻劃分的陣列數量,或通過指定要在其後進行劃分的列:
>>> from pprint import pprint
>>> a = np.floor(10*np.random.random((2,12)))
>>> a
array([[ 9., 3., 4., 1., 0., 0., 6.,7., 3., 4., 1., 1.], [ 1., 2.,8., 1., 0., 2., 1., 4., 3., 8.,1., 1.]])
>>> pprint(np.hsplit(a,3)) # 水平切成3等份
[array([[ 9., 3., 4., 1.],[ 1., 2.,8., 1.]]),
array([[ 0., 0., 6.,7.], [ 0., 2.,1., 4.]]),
array([[ 3., 4., 1.,1.],[ 3., 8.,1., 1.]])]
vsplit沿垂直軸分割,array_split允許指定沿哪個軸分割。
腦洞科技棧專注於人工智慧與量化投資領域