Python最好用的科學計算庫:NumPy快速入門教程(二)

Python最好用的科學計算庫:NumPy快速入門教程(二)

來自專欄深度學習+自然語言處理(NLP)5 人贊了文章

本文接上一篇:Python最好用的科學計算庫:NumPy快速入門教程(一)

形狀操作

首先導入numpy庫

>>> import numpy as np

改變數組的形狀

數組的形狀由每個維度的元素的數量決定。

>>> a = np.floor(10*np.random.random((3,4)))>>> aarray([[7., 1., 0., 7.], [7., 3., 3., 4.], [3., 9., 2., 9.]])>>> a.shape #數組的形狀(3, 4)

數組的形狀能夠通過很多命令改變。以下的三個命令都能返回一個被改變的數組,但是並不改變原數組。

>>> a.ravel() # 返回被平坦化的數組array([7., 1., 0., 7., 7., 3., 3., 4., 3., 9., 2., 9.])>>> a.reshape(6,2) # 返回一個改變形狀的數組array([[7., 1.], [0., 7.], [7., 3.], [3., 4.], [3., 9.], [2., 9.]])>>> a.T # 返回一個被轉置的數組array([[7., 7., 3.], [1., 3., 9.], [0., 3., 2.], [7., 4., 9.]])>>> a.T.shape(4, 3)>>> a.shape # 原數組的形狀不變(3, 4)

ravel()返回結果的元素順序一般來說C語言的風格,也就是說,最右的維度先變化,所以,返回結果的排列是a[0,0]之後是a[0,1]。如果數組的形狀改變了,依然會採用c語言風格的處理方式。NumPy一般生成數組在內存中就是按照這種順序存儲,所以ravel()一般不會複製參數,但是如果數組是通過切片或其他非一般的方式創建的,可能就需要複製了。ravel()reshape()函數也可以通過設置一個可選參數使用FORTRAN語言風格,這二種風格下,最左的維度先變化。

reshape函數返回的是改變了形狀數組,而resize方法改變的是數組本身的形狀。

>>> aarray([[7., 1., 0., 7.], [7., 3., 3., 4.], [3., 9., 2., 9.]])>>> a.resize((2,6))>>> a # resize 之後,a的形狀變了,這是與reshape的區別array([[7., 1., 0., 7., 7., 3.], [3., 4., 3., 9., 2., 9.]])

如果一個維度被設置為-1,那麼這個維度的大小將會自動計算。

>>> a.reshape(3,-1)array([[7., 1., 0., 7.], [7., 3., 3., 4.], [3., 9., 2., 9.]])

堆疊不同的數組

多個數組能夠沿著不同維度被堆疊在一起。

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

column_stack函數將一維數組看做列向量堆疊成二維數組。當被堆疊的數組是二維時,它的作用與hstack一樣。

>>> from numpy import newaxis>>> np.column_stack((a,b)) # 使用column_stack堆疊二維數組和上面我們使用hstack時得到的結果一樣array([[7., 8., 7., 4.], [1., 2., 2., 6.]])>>> a = np.array([4.,2.])>>> b = np.array([3.,8.])>>> np.column_stack((a,b)) # 當被堆疊的數組是一維數組時,返回的結果還是二維數組array([[4., 3.], [2., 8.]])>>> np.hstack((a,b)) # 使用hstack堆疊一維數組,返回的還是一維數組,這是與column_stack的不同array([4., 2., 3., 8.])>>> a[:,newaxis] # 通過newaxis能夠為數組添加維度array([[4.], [2.]])>>> np.column_stack((a[:,newaxis],b[:,newaxis]))array([[4., 3.], [2., 8.]])>>> np.hstack((a[:,newaxis],b[:,newaxis])) # 添加維度之後再使用hstack就可以得到和column_stack一樣的結果array([[4., 3.], [2., 8.]])

另外,對於任意數組row_stack與vstack的作用相同。通常,對於大於二維的數組,hstack作用在第二個維度上,而vstack作用在第一個維度上,而concatenate函數允許用戶通過設置一個可選參數決定連接應該發生在哪個維度。

注意

在一些複雜的情況下, 使用r_c_ 創建數組非常實用. 他們允許使用範圍表達符號:

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

當作用在數組時,r_ 和 c_ 的作用與vstack和hstack一樣,但是允許我們通過可選參數決定連接發生在哪個維度。

將數組拆分為更小的數組

使用hsplit,你可以沿著水平方向拆分數組,即可以通過指定平均切分的數量,也可以通過指定切分的列來實現。

>>> a = np.floor(10*np.random.random((2,12)))>>> aarray([[0., 2., 5., 6., 0., 2., 0., 2., 1., 5., 6., 2.], [3., 3., 2., 3., 6., 8., 8., 5., 6., 2., 0., 2.]])>>> np.hsplit(a,3) # 延水平方向切分為3個相同大小的數組[array([[0., 2., 5., 6.], [3., 3., 2., 3.]]), array([[0., 2., 0., 2.], [6., 8., 8., 5.]]), array([[1., 5., 6., 2.], [6., 2., 0., 2.]])]np.hsplit(a,(3,4)) # 從第3第4列切分a[array([[0., 2., 5.], [3., 3., 2.]]), array([[6.], [3.]]), array([[0., 2., 0., 2., 1., 5., 6., 2.], [6., 8., 8., 5., 6., 2., 0., 2.]])]

vsplit沿著垂直方向切分,array_split 可以指定沿著哪個維度切分。

複製與Views

當操作數組時,有時候數據被複制到一個新的數組,而有時候又沒有。這經常困擾新手,以下是三種情況。

不複製

簡單的賦值語句不會複製數組對象或者他們的值。

>>> a = np.arange(12)>>> b = a # 簡單的賦值不會複製新的對象>>> b is a # a和b是同一個數組的兩個不同的名稱而已True>>> b.shape = 3,4 # 改變b的話也會改變a>>> a.shape(3, 4)

Python將可變對象作為引用傳遞,因此函數調用不會複製。

>>> def f(x):... print(id(x))...>>> id(a) # id是一個對象的唯一標識符4557575552>>> f(a) # 將a傳入函數f,不會複製a4557575552

View或者淺複製

不同的數組對象能夠共享相同的數據。view方法創建一個新的數組對象,這個對象與原始數組使用相同的數據。

>>> c = a.view() # c是a的view,或者說c是a的淺複製,c是另一個對象>>> c is aFalse>>> c.base is a # 確切的說,c是數值的view,數值的屬於aTrue>>> c.flags.owndata #所以c的數值並不屬於cFalse>>> c.shape = 2,6 # 如果改變c的形狀,並不影響a>>> a.shape(3, 4)>>> c[0,4] = 1234 # 但是,如果改變c的數值,a也會受影響>>> aarray([[ 0, 1, 2, 3], [1234, 5, 6, 7], [ 8, 9, 10, 11]])

以上在python中稱作view,或者叫淺複製,切片操作就會返回一個view:

>>> s = a[ : , 1:3] # s是a的切片>>> s[:] = 10 # 改變s的值也會影響a>>> aarray([[ 0, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]])

深複製

copy方法生成一個數組的完整備份。

>>> d = a.copy() # 生成一個新的數組對象>>> d is aFalse>>> d.base is a # d與a不共享任何數值False>>> d[0,0] = 9999 #改變d的數值,也不會影響a>>> aarray([[ 0, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]])

函數和方法一覽

其他有用的方法列表可以查看這裡Routines

原文鏈接:docs.scipy.org/doc/nump


推薦閱讀:

numpy ndarray 之內功心法
Python最好用的科學計算庫:NumPy快速入門教程(一)
numpy的基本操作
科學計算:Python?VS.?MATLAB(3)

TAG:Python | 科學計算 | 科技 |