小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

 龔偉奇 2018-01-31

NumPy在數(shù)據(jù)分析就像Django在web開發(fā)中那樣出名,就是老大哥,也是在工作中最常用的庫,沒有之一,今天給大家詳細(xì)的講解一下這個庫的妙用!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

103456743

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

  • ndarray.ndim

    數(shù)組軸的個數(shù),在python的世界中,軸的個數(shù)被稱作秩

  • ndarray.shape

    數(shù)組的維度。這是一個指示數(shù)組在每個維度上大小的整數(shù)元組。例如一個n排m列的矩陣,它的shape屬性將是(2,3),這個元組的長度顯然是秩,即維度或者ndim屬性

  • ndarray.size

    數(shù)組元素的總個數(shù),等于shape屬性中元組元素的乘積。

  • ndarray.dtype

    一個用來描述數(shù)組中元素類型的對象,可以通過創(chuàng)造或指定dtype使用標(biāo)準(zhǔn)Python類型。另外NumPy提供它自己的數(shù)據(jù)類型。

  • ndarray.itemsize

    數(shù)組中每個元素的字節(jié)大小。例如,一個元素類型為float64的數(shù)組itemsiz屬性值為8(=64/8),又如,一個元素類型為complex32的數(shù)組item屬性為4(=32/8).

  • ndarray.data

    包含實際數(shù)組元素的緩沖區(qū),通常我們不需要使用這個屬性,因為我們總是通過索引來使用數(shù)組中的元素。

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

  • x[1,2,…] 等同于 x[1,2,:,:,:],

  • x[…,3] 等同于 x[:,:,:,:,3]

  • x[4,…,5,:] 等同 x[4,:,:,5,:].

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

進(jìn)階

廣播法則(rule)

廣播法則能使通用函數(shù)有意義地處理不具有相同形狀的輸入。

廣播第一法則是,如果所有的輸入數(shù)組維度不都相同,一個“1”將被重復(fù)地添加在維度較小的數(shù)組上直至所有的數(shù)組擁有一樣的維度。

廣播第二法則確定長度為1的數(shù)組沿著特殊的方向表現(xiàn)地好像它有沿著那個方向最大形狀的大小。對數(shù)組來說,沿著那個維度的數(shù)組元素的值理應(yīng)相同。

應(yīng)用廣播法則之后,所有數(shù)組的大小必須匹配。更多細(xì)節(jié)可以從這個文檔找到。

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

第二種通過布爾來索引的方法更近似于整數(shù)索引;對數(shù)組的每個維度我們給一個一維布爾數(shù)組來選擇我們想要的切片。

>>> a = arange(12).reshape(3,4) >>> b1 = array([False,True,True]) # first dim selection >>> b2 = array([True,False,True,False]) # second dim selection >>> >>> a[b1,:] # selecting rows array([[ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> >>> a[b1] # same thing array([[ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> >>> a[:,b2] # selecting columns array([[ 0, 2], [ 4, 6], [ 8, 10]]) >>> >>> a[b1,b2] # a weird thing to do array([ 4, 10])

注意一維數(shù)組的長度必須和你想要切片的維度或軸的長度一致,在之前的例子中,b1是一個秩為1長度為三的數(shù)組(a的行數(shù)),b2(長度為4)與a的第二秩(列)相一致。7

ix_()函數(shù)

ix_函數(shù)可以為了獲得多元組的結(jié)果而用來結(jié)合不同向量。例如,如果你想要用所有向量a、b和c元素組成的三元組來計算a b*c

>>> a = array([2,3,4,5]) >>> b = array([8,5,4]) >>> c = array([5,4,6,8,3]) >>> ax,bx,cx = ix_(a,b,c) >>> ax array([[[2]], [[3]], [[4]], [[5]]]) >>> bx array([[[8], [5], [4]]]) >>> cx array([[[5, 4, 6, 8, 3]]]) >>> ax.shape, bx.shape, cx.shape ((4, 1, 1), (1, 3, 1), (1, 1, 5)) >>> result = ax bx*cx >>> result array([[[42, 34, 50, 66, 26], [27, 22, 32, 42, 17], [22, 18, 26, 34, 14]], [[43, 35, 51, 67, 27], [28, 23, 33, 43, 18], [23, 19, 27, 35, 15]], [[44, 36, 52, 68, 28], [29, 24, 34, 44, 19], [24, 20, 28, 36, 16]], [[45, 37, 53, 69, 29], [30, 25, 35, 45, 20], [25, 21, 29, 37, 17]]]) >>> result[3,2,4] 17 >>> a[3] b[2]*c[4] 17

你也可以實行如下簡化:

def ufunc_reduce(ufct, *vectors): vs = ix_(*vectors) r = ufct.identity for v in vs: r = ufct(r,v) return r

然后這樣使用它:

>>> ufunc_reduce(add,a,b,c) array([[[15, 14, 16, 18, 13], [12, 11, 13, 15, 10], [11, 10, 12, 14, 9]], [[16, 15, 17, 19, 14], [13, 12, 14, 16, 11], [12, 11, 13, 15, 10]], [[17, 16, 18, 20, 15], [14, 13, 15, 17, 12], [13, 12, 14, 16, 11]], [[18, 17, 19, 21, 16], [15, 14, 16, 18, 13], [14, 13, 15, 17, 12]]])

這個reduce與ufunc.reduce(比如說add.reduce)相比的優(yōu)勢在于它利用了廣播法則,避免了創(chuàng)建一個輸出大小乘以向量個數(shù)的參數(shù)數(shù)組。8

用字符串索引

參見RecordArray。

線性代數(shù)

繼續(xù)前進(jìn),基本線性代數(shù)包含在這里。

簡單數(shù)組運(yùn)算

參考numpy文件夾中的linalg.py獲得更多信息

>>> from numpy import * >>> from numpy.linalg import * >>> a = array([[1.0, 2.0], [3.0, 4.0]]) >>> print a [[ 1. 2.] [ 3. 4.]] >>> a.transpose() array([[ 1., 3.], [ 2., 4.]]) >>> inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> u = eye(2) # unit 2x2 matrix; 'eye' represents 'I' >>> u array([[ 1., 0.], [ 0., 1.]]) >>> j = array([[0.0, -1.0], [1.0, 0.0]]) >>> dot (j, j) # matrix product array([[-1., 0.], [ 0., -1.]]) >>> trace(u) # trace 2.0 >>> y = array([[5.], [7.]]) >>> solve(a, y) array([[-3.], [ 4.]]) >>> eig(j) (array([ 0. 1.j, 0.-1.j]), array([[ 0.70710678 0.j, 0.70710678 0.j], [ 0.00000000-0.70710678j, 0.00000000 0.70710678j]])) Parameters: square matrix Returns The eigenvalues, each repeated according to its multiplicity. The normalized (unit 'length') eigenvectors, such that the column ``v[:,i]`` is the eigenvector corresponding to the eigenvalue ``w[i]`` .

矩陣類

這是一個關(guān)于矩陣類的簡短介紹。

>>> A = matrix('1.0 2.0; 3.0 4.0') >>> A [[ 1. 2.] [ 3. 4.]] >>> type(A) # file where class is defined <class 'numpy.matrixlib.defmatrix.matrix'> >>> A.T # transpose [[ 1. 3.] [ 2. 4.]] >>> X = matrix('5.0 7.0') >>> Y = X.T >>> Y [[5.] [7.]] >>> print A*Y # matrix multiplication [[19.] [43.]] >>> print A.I # inverse [[-2. 1. ] [ 1.5 -0.5]] >>> solve(A, Y) # solving linear equation matrix([[-3.], [ 4.]])

索引:比較矩陣和二維數(shù)組

注意NumPy中數(shù)組和矩陣有些重要的區(qū)別。NumPy提供了兩個基本的對象:一個N維數(shù)組對象和一個通用函數(shù)對象。其它對象都是建構(gòu)在它們之上 的。特別的,矩陣是繼承自NumPy數(shù)組對象的二維數(shù)組對象。對數(shù)組和矩陣,索引都必須包含合適的一個或多個這些組合:整數(shù)標(biāo)量、省略號 (ellipses)、整數(shù)列表;布爾值,整數(shù)或布爾值構(gòu)成的元組,和一個一維整數(shù)或布爾值數(shù)組。矩陣可以被用作矩陣的索引,但是通常需要數(shù)組、列表或者 其它形式來完成這個任務(wù)。

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

現(xiàn)在有些和Python索引不同的了:你可以同時使用逗號分割索引來沿著多個軸索引。

>>> print A[:,1]; print A[:,1].shape [1 5 9] (3,) >>> print M[:,1]; print M[:,1].shape [[1] [5] [9]] (3, 1)

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

>>> A[:,[1,3]] array([[ 1, 3], [ 5, 7], [ 9, 11]])

稍微復(fù)雜點的方法是使用take()方法(method):

>>> A[:,].take([1,3],axis=1) array([[ 1, 3], [ 5, 7], [ 9, 11]])

如果我們想跳過第一行,我們可以這樣:

>>> A[1:,].take([1,3],axis=1) array([[ 5, 7], [ 9, 11]])

或者我們僅僅使用A[1:,[1,3]]。還有一種方法是通過矩陣向量積(叉積)。

>>> A[ix_((1,2),(1,3))] array([[ 5, 7], [ 9, 11]])

為了讀者的方便,在次寫下之前的矩陣:

>>> A[ix_((1,2),(1,3))] array([[ 5, 7], [ 9, 11]])

現(xiàn)在讓我們做些更復(fù)雜的。比如說我們想要保留第一行大于1的列。一種方法是創(chuàng)建布爾索引:

>>> A[0,:]>1 array([False, False, True, True], dtype=bool) >>> A[:,A[0,:]>1] array([[ 2, 3], [ 6, 7], [10, 11]])

就是我們想要的!但是索引矩陣沒這么方便。

>>> M[0,:]>1 matrix([[False, False, True, True]], dtype=bool) >>> M[:,M[0,:]>1] matrix([[2, 3]])

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

技巧和提示

下面我們給出簡短和有用的提示。

“自動”改變形狀

更改數(shù)組的維度,你可以省略一個尺寸,它將被自動推導(dǎo)出來。

>>> a = arange(30) >>> a.shape = 2,-1,3 # -1 means 'whatever is needed' >>> a.shape (2, 5, 3) >>> a array([[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14]], [[15, 16, 17], [18, 19, 20], [21, 22, 23], [24, 25, 26], [27, 28, 29]]])

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

2 NumPy-快速處理數(shù)據(jù)

標(biāo)準(zhǔn)安裝的Python中用列表(list)保存一組值,可以用來當(dāng)作數(shù)組使用,不過由于列表的元素可以是任何對象,因此列表中所保存的是對象的指針。這樣為了保存一個簡單的[1,2,3],需要有3個指針和三個整數(shù)對象。對于數(shù)值運(yùn)算來說這種結(jié)構(gòu)顯然比較浪費(fèi)內(nèi)存和CPU計算時間。

此外Python還提供了一個array模塊,array對象和列表不同,它直接保存數(shù)值,和C語言的一維數(shù)組比較類似。但是由于它不支持多維,也沒有各種運(yùn)算函數(shù),因此也不適合做數(shù)值運(yùn)算。

NumPy的誕生彌補(bǔ)了這些不足,NumPy提供了兩種基本的對象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray(下文統(tǒng)一稱之為數(shù)組)是存儲單一數(shù)據(jù)類型的多維數(shù)組,而ufunc則是能夠?qū)?shù)組進(jìn)行處理的函數(shù)。

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

數(shù)組的大小可以通過其shape屬性獲得:

>>> a.shape(4,)>>> c.shape(3, 4)

數(shù)組a的shape只有一個元素,因此它是一維數(shù)組。而數(shù)組c的shape有兩個元素,因此它是二維數(shù)組,其中第0軸的長度為3,第1軸的長度為4。還可以通過修改數(shù)組的shape屬性,在保持?jǐn)?shù)組元素個數(shù)不變的情況下,改變數(shù)組每個軸的長度。下面的例子將數(shù)組c的shape改為(4,3),注意從(3,4)改為(4,3)并不是對數(shù)組進(jìn)行轉(zhuǎn)置,而只是改變每個軸的大小,數(shù)組元素在內(nèi)存中的位置并沒有改變:

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

數(shù)組的元素類型可以通過dtype屬性獲得。上面例子中的參數(shù)序列的元素都是整數(shù),因此所創(chuàng)建的數(shù)組的元素類型也是整數(shù),并且是32bit的長整型??梢酝ㄟ^dtype參數(shù)在創(chuàng)建時指定元素類型:

>>> np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]], dtype=np.float)array([[ 1., 2., 3., 4.], [ 4., 5., 6., 7.], [ 7., 8., 9., 10.]])>>> np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]], dtype=np.complex)array([[ 1. 0.j, 2. 0.j, 3. 0.j, 4. 0.j], [ 4. 0.j, 5. 0.j, 6. 0.j, 7. 0.j], [ 7. 0.j, 8. 0.j, 9. 0.j, 10. 0.j]])

上面的例子都是先創(chuàng)建一個Python序列,然后通過array函數(shù)將其轉(zhuǎn)換為數(shù)組,這樣做顯然效率不高。因此NumPy提供了很多專門用來創(chuàng)建數(shù)組的函數(shù)。下面的每個函數(shù)都有一些關(guān)鍵字參數(shù),具體用法請查看函數(shù)說明。

  • arange函數(shù)類似于python的range函數(shù),通過指定開始值、終值和步長來創(chuàng)建一維數(shù)組,注意數(shù)組不包括終值:

    >>> np.arange(0,1,0.1)array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
  • linspace函數(shù)通過指定開始值、終值和元素個數(shù)來創(chuàng)建一維數(shù)組,可以通過endpoint關(guān)鍵字指定是否包括終值,缺省設(shè)置是包括終值:

    >>> np.linspace(0, 1, 12)array([ 0. , 0.09090909, 0.18181818, 0.27272727, 0.36363636, 0.45454545, 0.54545455, 0.63636364, 0.72727273, 0.81818182, 0.90909091, 1. ])
  • logspace函數(shù)和linspace類似,不過它創(chuàng)建等比數(shù)列,下面的例子產(chǎn)生1(10^0)到100(10^2)、有20個元素的等比數(shù)列:

    >>> np.logspace(0, 2, 20)array([ 1. , 1.27427499, 1.62377674, 2.06913808, 2.6366509 , 3.35981829, 4.2813324 , 5.45559478, 6.95192796, 8.8586679 , 11.28837892, 14.38449888, 18.32980711, 23.35721469, 29.76351442, 37.92690191, 48.32930239, 61.58482111, 78.47599704, 100. ])

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

使用布爾數(shù)組

當(dāng)使用布爾數(shù)組b作為下標(biāo)存取數(shù)組x中的元素時,將收集數(shù)組x中所有在數(shù)組b中對應(yīng)下標(biāo)為True的元素。使用布爾數(shù)組作為下標(biāo)獲得的數(shù)組不和原始數(shù)組共享數(shù)據(jù)空間,注意這種方式只對應(yīng)于布爾數(shù)組,不能使用布爾列表。

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

.1.3 多維數(shù)組

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

多維數(shù)組的存取和一維數(shù)組類似,因為多維數(shù)組有多個軸,因此它的下標(biāo)需要用多個值來表示,NumPy采用組元(tuple)作為數(shù)組的下標(biāo)。如圖2.1所示,a為一個6x6的數(shù)組,圖中用顏色區(qū)分了各個下標(biāo)以及其對應(yīng)的選擇區(qū)域。

組元不需要圓括號

雖然我們經(jīng)常在Python中用圓括號將組元括起來,但是其實組元的語法定義只需要用逗號隔開即可,例如 x,y=y,x 就是用組元交換變量值的一個例子。

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

  • a[(0,1,2,3,4),(1,2,3,4,5)] : 用于存取數(shù)組的下標(biāo)和仍然是一個有兩個元素的組元,組元中的每個元素都是整數(shù)序列,分別對應(yīng)數(shù)組的第0軸和第1軸。從兩個序列的對應(yīng)位置取出兩個整數(shù)組成下標(biāo): a[0,1], a[1,2], ..., a[4,5]。

  • a[3:, [0, 2, 5]] : 下標(biāo)中的第0軸是一個范圍,它選取第3行之后的所有行;第1軸是整數(shù)序列,它選取第0, 2, 5三列。

  • a[mask, 2] : 下標(biāo)的第0軸是一個布爾數(shù)組,它選取第0,2,5行;第1軸是一個整數(shù),選取第2列。

2.1.4 結(jié)構(gòu)數(shù)組

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

在C語言中我們可以通過struct關(guān)鍵字定義結(jié)構(gòu)類型,結(jié)構(gòu)中的字段占據(jù)連續(xù)的內(nèi)存空間,每個結(jié)構(gòu)體占用的內(nèi)存大小都相同,因此可以很容易地定義結(jié)構(gòu)數(shù)組。和C語言一樣,在NumPy中也很容易對這種結(jié)構(gòu)數(shù)組進(jìn)行操作。只要NumPy中的結(jié)構(gòu)定義和C語言中的定義相同,NumPy就可以很方便地讀取C語言的結(jié)構(gòu)數(shù)組的二進(jìn)制數(shù)據(jù),轉(zhuǎn)換為NumPy的結(jié)構(gòu)數(shù)組。

假設(shè)我們需要定義一個結(jié)構(gòu)數(shù)組,它的每個元素都有name, age和weight字段。在NumPy中可以如下定義

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

內(nèi)存對齊

C語言的結(jié)構(gòu)體為了內(nèi)存尋址方便,會自動的添加一些填充用的字節(jié),這叫做內(nèi)存對齊。例如如果把下面的name[32]改為name[30]的話,由于內(nèi)存對齊問題,在name和age中間會填補(bǔ)兩個字節(jié),最終的結(jié)構(gòu)體大小不會改變。因此如果numpy中的所配置的內(nèi)存大小不符合C語言的對齊規(guī)范的話,將會出現(xiàn)數(shù)據(jù)錯位。為了解決這個問題,在創(chuàng)建dtype對象時,可以傳遞參數(shù)align=True,這樣numpy的結(jié)構(gòu)數(shù)組的內(nèi)存對齊和C語言的結(jié)構(gòu)體就一致了。

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

用下面的字典參數(shù)也可以定義結(jié)構(gòu)類型,字典的關(guān)鍵字為結(jié)構(gòu)中字段名,值為字段的類型描述,但是由于字典的關(guān)鍵字是沒有順序的,因此字段的順序需要在類型描述中給出,類型描述是一個組元,它的第二個值給出字段的字節(jié)為單位的偏移量,例如age字段的偏移量為25個字節(jié):

>>> np.dtype({'surname':('S25',0),'age':(np.uint8,25)})dtype([('surname', '|S25'), ('age', '|u1')])

2.1.5 內(nèi)存結(jié)構(gòu)

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

下面讓我們來看看ndarray數(shù)組對象是如何在內(nèi)存中儲存的。如圖2.3所示,關(guān)于數(shù)組的描述信息保存在一個數(shù)據(jù)結(jié)構(gòu)中,這個結(jié)構(gòu)引用兩個對象:一塊用于保存數(shù)據(jù)的存儲區(qū)域和一個用于描述元素類型的dtype對象。

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

sin函數(shù)的第二個參數(shù)也是x,那么它所做的事情就是對x中的每給值求正弦值,并且把結(jié)果保存到x中的對應(yīng)的位置中。此時函數(shù)的返回值仍然是整個計算的結(jié)果,只不過它就是x,因此兩個變量的id是相同的(變量t和變量x指向同一塊內(nèi)存區(qū)域)。

我用下面這個小程序,比較了一下numpy.math和Python標(biāo)準(zhǔn)庫的math.sin的計算速度::

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

請注意numpy.sin的計算速度只有math.sin的1/5。這是因為numpy.sin為了同時支持?jǐn)?shù)組和單個值的計算,其C語言的內(nèi)部實現(xiàn)要比math.sin復(fù)雜很多,如果我們同樣在Python級別進(jìn)行循環(huán)的話,就會看出其中的差別了。此外,numpy.sin返回的數(shù)的類型和math.sin返回的類型有所不同,math.sin返回的是Python的標(biāo)準(zhǔn)float類型,而numpy.sin則返回一個numpy.float64類型:

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

由于Python的操作符重載功能,計算兩個數(shù)組相加可以簡單地寫為a b,而np.add(a,b,a)則可以用a =b來表示。下面是數(shù)組的運(yùn)算符和其對應(yīng)的ufunc函數(shù)的一個列表,注意除號'/'的意義根據(jù)是否激活__future__.division有所不同。

y = x1 x2:add(x1, x2 [, y])
y = x1 - x2:subtract(x1, x2 [, y])
y = x1 * x2:multiply (x1, x2 [, y])
y = x1 / x2:divide (x1, x2 [, y]), 如果兩個數(shù)組的元素為整數(shù),那么用整數(shù)除法
y = x1 / x2:true divide (x1, x2 [, y]), 總是返回精確的商
y = x1 // x2:floor divide (x1, x2 [, y]), 總是對返回值取整
y = -x:negative(x [,y])
y = x1**x2:power(x1, x2 [, y])
y = x1 % x2:remainder(x1, x2 [, y]), mod(x1, x2, [, y])

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

值得注意的是用frompyfunc得到的函數(shù)計算出的數(shù)組元素的類型為object,因為frompyfunc函數(shù)無法保證Python函數(shù)返回的數(shù)據(jù)類型都完全一致。因此還需要再次 y2.astype(np.float64)將其轉(zhuǎn)換為雙精度浮點數(shù)組。

2.2.1 廣播

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

當(dāng)我們使用ufunc函數(shù)對兩個數(shù)組進(jìn)行計算時,ufunc函數(shù)會對這兩個數(shù)組的對應(yīng)元素進(jìn)行計算,因此它要求這兩個數(shù)組有相同的大小(shape相同)。如果兩個數(shù)組的shape不同的話,會進(jìn)行如下的廣播(broadcasting)處理:

  1. 讓所有輸入數(shù)組都向其中shape最長的數(shù)組看齊,shape中不足的部分都通過在前面加1補(bǔ)齊

  2. 輸出數(shù)組的shape是輸入數(shù)組shape的各個軸上的最大值

  3. 如果輸入數(shù)組的某個軸和輸出數(shù)組的對應(yīng)軸的長度相同或者其長度為1時,這個數(shù)組能夠用來計算,否則出錯

  4. 當(dāng)輸入數(shù)組的某個軸的長度為1時,沿著此軸運(yùn)算時都用此軸上的第一組值

上述4條規(guī)則理解起來可能比較費(fèi)勁,讓我們來看一個實際的例子。

先創(chuàng)建一個二維數(shù)組a,其shape為(6,1):

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

這樣加法運(yùn)算的兩個輸入數(shù)組的shape分別為(6,1)和(1,5),根據(jù)規(guī)則2,輸出數(shù)組的各個軸的長度為輸入數(shù)組各個軸上的長度的最大值,可知輸出數(shù)組的shape為(6,5)。

由于b的第0軸上的長度為1,而a的第0軸上的長度為6,因此為了讓它們在第0軸上能夠相加,需要將b在第0軸上的長度擴(kuò)展為6,這相當(dāng)于:

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

ogrid是一個很有趣的對象,它像一個多維數(shù)組一樣,用切片組元作為下標(biāo)進(jìn)行存取,返回的是一組可以用來廣播計算的數(shù)組。其切片下標(biāo)有兩種形式:

  • 開始值:結(jié)束值:步長,和np.arange(開始值, 結(jié)束值, 步長)類似

  • 開始值:結(jié)束值:長度j,當(dāng)?shù)谌齻€參數(shù)為虛數(shù)時,它表示返回的數(shù)組的長度,和np.linspace(開始值, 結(jié)束值, 長度)類似:

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

.2.2 ufunc的方法

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

ufunc函數(shù)本身還有些方法,這些方法只對兩個輸入一個輸出的ufunc函數(shù)有效,其它的ufunc對象調(diào)用這些方法時會拋出ValueError異常。

reduce 方法和Python的reduce函數(shù)類似,它沿著axis軸對array進(jìn)行操作,相當(dāng)于將<op>運(yùn)算符插入到沿axis軸的所有子數(shù)組或者元素當(dāng)中。

<op>.reduce (array=, axis=0, dtype=None)

例如:

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

if indices[i] < indices[i 1]: result[i] = np.reduce(a[indices[i]:indices[i 1]]) else: result[i] = a[indices[i]

而最后一個元素如下計算:

np.reduce(a[indices[-1]:])

因此上面例子中,結(jié)果的每個元素如下計算而得:

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

2.3 矩陣運(yùn)算

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

NumPy和Matlab不一樣,對于多維數(shù)組的運(yùn)算,缺省情況下并不使用矩陣運(yùn)算,如果你希望對數(shù)組進(jìn)行矩陣運(yùn)算的話,可以調(diào)用相應(yīng)的函數(shù)。

matrix對象

numpy庫提供了matrix類,使用matrix類創(chuàng)建的是矩陣對象,它們的加減乘除運(yùn)算缺省采用矩陣方式計算,因此用法和matlab十分類似。但是由于NumPy中同時存在ndarray和matrix對象,因此用戶很容易將兩者弄混。這有違Python的“顯式優(yōu)于隱式”的原則,因此并不推薦在較復(fù)雜的程序中使用matrix。下面是使用matrix的一個例子:

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

使用numpy.savetxt和numpy.loadtxt可以讀寫1維和2維的數(shù)組:

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!

Python最牛逼數(shù)據(jù)分析庫!月薪35K大牛:整理的NumPy詳細(xì)教程!


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多