NumPy之二:數組形狀操作

1. 改變數組形狀

給定了每個axis上元素的數量,一個數組的形狀就固定了。

>>> a = np.floor(10*np.random.random((3,4)))
>>> a
array([[ 2.,  8.,  0.,  6.],
       [ 4.,  5.,  1.,  1.],
       [ 8.,  9.,  3.,  6.]])
>>> a.shape
(3, 4)

通過一些命令,我們可以改變數組的形狀:

>>> a.ravel() # flatten the array
array([ 2.,  8.,  0.,  6.,  4.,  5.,  1.,  1.,  8.,  9.,  3.,  6.])
>>> a.shape = (6, 2)
>>> a.T
array([[ 2.,  0.,  4.,  1.,  8.,  3.],
       [ 8.,  6.,  5.,  1.,  9.,  6.]])

reshape函數返回其參數指定的形狀的數組,而ndarray.resize方法則會直接修改數組本身:

>>> a
array([[ 2.,  8.],
       [ 0.,  6.],
       [ 4.,  5.],
       [ 1.,  1.],
       [ 8.,  9.],
       [ 3.,  6.]])
>>> a.resize((2,6))
>>> a
array([[ 2.,  8.,  0.,  6.,  4.,  5.],
       [ 1.,  1.,  8.,  9.,  3.,  6.]])

如果在reshape操作中,某個維指定爲-1,則其他維會自動計算

>>> c
array([[[  0,   1,   2],
        [ 10,  12,  13]],

       [[100, 101, 102],
        [110, 112, 113]]])
>>> c.shape
(2, 2, 3)
>>> c.reshape(3,-1)
array([[  0,   1,   2,  10],
       [ 12,  13, 100, 101],
       [102, 110, 112, 113]])
>>> c.reshape(3,2,-1)
array([[[  0,   1],
        [  2,  10]],

       [[ 12,  13],
        [100, 101]],

       [[102, 110],
        [112, 113]]])
>>> c.reshape(3,-1,2)
array([[[  0,   1],
        [  2,  10]],

       [[ 12,  13],
        [100, 101]],

       [[102, 110],
        [112, 113]]])

2. 數組堆疊

一些數組可以沿着不同的axis進行堆疊。

>>> a = np.floor(10*np.random.random((2,2)))
>>> a
array([[ 8.,  8.],
       [ 0.,  0.]])
>>> b = np.floor(10*np.random.random((2,2)))
>>> b
array([[ 1.,  8.],
       [ 0.,  4.]])
>>> np.vstack((a,b))
array([[ 8.,  8.],
       [ 0.,  0.],
       [ 1.,  8.],
       [ 0.,  4.]])
>>> np.hstack((a,b))
array([[ 8.,  8.,  1.,  8.],
       [ 0.,  0.,  0.,  4.]])

函數column_stack可以將一維數組作爲列堆疊到二維數組上。一維數組會先被轉化成二維的列數組。

>>> from numpy import newaxis
>>> a
array([[ 5.,  4.],
       [ 8.,  7.]])
>>> z
array([20, 30])
>>> np.column_stack((a,z))
array([[  5.,   4.,  20.],
       [  8.,   7.,  30.]])

等價於以下過程

>>> a
array([[ 5.,  4.],
       [ 8.,  7.]])
>>> z
array([20, 30])
>>> z = z[ : , newaxis]
>>> z
array([[20],
       [30]])
>>> np.hstack((a,z))
array([[  5.,   4.,  20.],
       [  8.,   7.,  30.]])

當然,column_stack也可以作用於兩個多維數組,等價於hstack.

>>> np.column_stack((a,b))   # With 2D arrays
array([[ 8.,  8.,  1.,  8.],
       [ 0.,  0.,  0.,  4.]])
>>> a = np.array([4.,2.])
>>> b = np.array([2.,8.])
>>> a[:,newaxis]  # This allows to have a 2D columns vector
array([[ 4.],
       [ 2.]])
>>> np.column_stack((a[:,newaxis],b[:,newaxis]))
array([[ 4.,  2.],
       [ 2.,  8.]])
>>> np.vstack((a[:,newaxis],b[:,newaxis])) # The behavior of vstack is different
array([[ 4.],
       [ 2.],
       [ 2.],
       [ 8.]])

對於多於二維的數組,hstack沿着數組第二個axis進行堆疊,vstack沿着第一個axis堆疊。concatenate函數允許指定axis進行堆疊,比如numpy.concatenate((a1, a2, …), axis=0)

在複雜點的例子中,r_ 和 c_ 對通過堆疊創建數組是很有用的。它們允許使用區間功能“:”:

>>> np.r_[1:4,0,4]
array([1, 2, 3, 0, 4])

如果使用數組作爲參數,r_ 和 c_ 默認情況下和vstack和hstack很相似,但他們允許使用一個可選參數來指定axis進行堆疊。

3. 分離數組

使用hsplit函數,可以將一個數組沿着其橫軸切分開,可以指定返回的特定形狀的數組數量,或者指定分界應該出現在哪些列上(注意列不是索引,列從1開始計數):

>>> a = np.floor(10*np.random.random((2,12)))
>>> a
array([[ 9.,  5.,  6.,  3.,  6.,  8.,  0.,  7.,  9.,  7.,  2.,  7.],
       [ 1.,  4.,  9.,  2.,  2.,  1.,  0.,  6.,  2.,  2.,  4.,  0.]])
>>> np.hsplit(a,3)   # Split a into 3
[array([[ 9.,  5.,  6.,  3.],
       [ 1.,  4.,  9.,  2.]]), array([[ 6.,  8.,  0.,  7.],
       [ 2.,  1.,  0.,  6.]]), array([[ 9.,  7.,  2.,  7.],
       [ 2.,  2.,  4.,  0.]])]
>>> np.hsplit(a,(3,4))   # Split a after the third and the fourth column
[array([[ 9.,  5.,  6.],
       [ 1.,  4.,  9.]]), array([[ 3.],
       [ 2.]]), array([[ 6.,  8.,  0.,  7.,  9.,  7.,  2.,  7.],
       [ 2.,  1.,  0.,  6.,  2.,  2.,  4.,  0.]])]

vsplit沿着縱軸切割數組,array_split函數則可以指定要沿着哪個軸(axis)切割。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章