NumPy(Numerical Python的簡稱)是高性能科學(xué)計算和數(shù)據(jù)分析的基礎(chǔ)包。其部分功能包括:
- ndarray ,一個具有矢量算術(shù)運算和復(fù)雜廣播能力的快速且節(jié)省空間的多維數(shù)組。
- 用于對整組數(shù)據(jù)進(jìn)行快速運算的標(biāo)準(zhǔn)數(shù)學(xué)函數(shù)(無需編寫循環(huán))
- 用于讀寫磁盤數(shù)據(jù)的工具以及用于操作內(nèi)存內(nèi)存映射文件的工具。
- 線性代數(shù)、隨機(jī)數(shù)生成以及傅里葉變換功能。
- 用于集成有C++,C,F(xiàn)ortran等編程語言的代碼工具。
對于大部分?jǐn)?shù)據(jù)分析應(yīng)用而言,我最關(guān)注的功能主要集中在:
- 用于數(shù)據(jù)整理和清理、子集構(gòu)造和過濾、轉(zhuǎn)換等快速的矢量化數(shù)組運算。
- 通常的數(shù)組加法,如排序、唯一化、集合運算等。
- 高效的描述統(tǒng)計和數(shù)據(jù)聚合/摘要運算。
- 用于異構(gòu)數(shù)據(jù)集的合并/連接運算的數(shù)據(jù)對齊和關(guān)系型數(shù)據(jù)運算
- 將條件邏輯表述為數(shù)組表達(dá)式(而不是帶有if-elif-else分支的循環(huán))
- 數(shù)據(jù)的分組運算(集合、轉(zhuǎn)換、函數(shù)應(yīng)用等)
一、NumPy的ndarray:一組多維數(shù)組對象
NumPy最重要的一個特點就是:其N維數(shù)組對象(即ndarray),該對象是一個快速而靈活的大數(shù)據(jù)集容器,可以利用這種數(shù)組對整塊數(shù)據(jù)執(zhí)行一些數(shù)學(xué)運算。
ndarray是一個通用的同構(gòu)數(shù)據(jù)多維容器,也就是說,其中的所有元素必須是相同類型的。每個數(shù)組都有一個shape(一個表示各維度大小的元組)和一個dtype(一個用于說明數(shù)據(jù)類型的對象)
1.創(chuàng)建ndarray
創(chuàng)建數(shù)組最簡單的方法就是使用array函數(shù)。它接受一切序列型的對象(包括其他數(shù)組),然后產(chǎn)生一個新的含有傳入數(shù)據(jù)的NumPy的數(shù)組。
嵌套序列(比如由一組等長列表組成的列表),將會被轉(zhuǎn)換成一個多維數(shù)組。
注:np.array會嘗試為新建的這個數(shù)組推斷出一個較為合適的數(shù)據(jù)類型。數(shù)據(jù)類型保存在一個特殊的dtype對象中。
除了np.array之外,還有一些函數(shù)也可以新建數(shù)組。比如zeros和ones分別可以創(chuàng)建指定長度或形狀的全0或全1數(shù)組。empty可以創(chuàng)建一個沒有任何具體值的數(shù)組。要用這些方法創(chuàng)建多維數(shù)組,只需傳入一個表示形狀的元組即可。
arange 是python內(nèi)置函數(shù)range的數(shù)組版.
由于NumPy關(guān)注的是數(shù)值計算,因此,如果沒有特別指定,數(shù)據(jù)類型基本都是fioat64(浮點數(shù))
array 將輸入數(shù)據(jù)(列表、元組、數(shù)組或其他序列類型)轉(zhuǎn)換為ndarry。要么推斷出dtype,要么顯示指定dtype。默認(rèn)直接復(fù)制輸入數(shù)據(jù)。
asarray 將輸入轉(zhuǎn)化為ndarray,如果輸入本身就是一個ndarray就不進(jìn)行復(fù)制。
arange類似內(nèi)置的range,但返回的是一個ndarray,而不是列表。
ones、ones_like根據(jù)指定形狀和dtype創(chuàng)建一個全1數(shù)組。 ones_like以另一個數(shù)組為參數(shù),并根據(jù)其形狀和dtype創(chuàng)建一個全1數(shù)組。
zeros、zeros_like類似于ones、ones_like,只不過產(chǎn)生的是全0數(shù)組而已。
eye、identity創(chuàng)建一個正方的N*N單位矩陣(對角線為1,其余為0)
2.ndarray的數(shù)據(jù)類型
dtype(數(shù)據(jù)類型)是一個特殊的對象,它含有ndarray將一塊內(nèi)存解釋為特定數(shù)據(jù)類型所需的信息。
數(shù)值形dtype的命名方式相同:一個類型名(如float或int),后面跟一個用于表示各元素位長的數(shù)字。
- 可以通過ndarray的astype方法顯式地轉(zhuǎn)化其dtype。
- 注:調(diào)用astype無論如何都會創(chuàng)建一個新的數(shù)組(原始數(shù)據(jù)的一份拷貝),即使新dtype跟老dtype相同也是如此。
3.數(shù)組和標(biāo)量之間的運算
數(shù)組很重要,因為它使你不用編寫循環(huán)即可對數(shù)據(jù)執(zhí)行批量運算。這通常就叫做矢量化。大小相等的數(shù)組之間的任何算術(shù)運算都會將運算應(yīng)用到元素級。
同樣,數(shù)組與標(biāo)量的算術(shù)運算也會將那個標(biāo)量值傳播到各個元素。
不同大小的數(shù)組之間的運算叫做廣播
4.基本的索引和切片
NumPy數(shù)組的索引是一個內(nèi)容豐富的主題,因為選取數(shù)據(jù)子集或單個元素的方式有限多。
當(dāng)你將一個標(biāo)量值賦值給一個切片時(如arr[5:8]=12),該值會自動傳播到整個選區(qū)。跟列表最重要的區(qū)別在于,數(shù)組切片是原始數(shù)組的視圖。這意味著數(shù)據(jù)不會被復(fù)制,視圖上的任何修改都會直接反映到源數(shù)組上。
注:如果你想得到的是ndarray切片的一份副本而非視圖,就需要顯式地進(jìn)行復(fù)制操作,例如:arr[5:8].copy()
對于高維度數(shù)組,能做的事情更多。在一個二維數(shù)組中,各索引位置上的元素不再是標(biāo)量而是一維數(shù)組。
可以對各個元素進(jìn)行遞歸訪問,但這樣需要做的事情有點多??梢詡魅胍粋€以逗號隔開的索引列表來獲取單個元素。也就是說,下面兩種方式是等價的:arr2d[0][2]
arr2d[0,2]
在多維數(shù)組中,如果省略了后面的索引,則返回對象會是一個維度低一點的ndarray(它含有高一級維度上的所有數(shù)據(jù))
5.切片索引
ndarray的切片語法跟Python列表這樣的一維對象差不多
高維度對象的花樣更多,你可以在一個或多個軸上進(jìn)行切片,也可以跟整數(shù)索引混合使用。它是沿著第0軸(即第一個軸切片的)。也就是說,切片是沿著一個軸向選取元素的,可以一次傳入多個切片,就像傳入多個索引那樣。
arr2d[ :2,1: ]注:括號外面的“維度”是一維、二維、三維、四維之類的意思,而括號里面的應(yīng)該理解為“軸”。
注:“只有冒號”表示選取整個軸
6.布爾型索引
布爾型數(shù)組的長度必須跟被索引的軸的長度一致。此外,還可以將布爾型數(shù)組跟切片、整數(shù)(或整數(shù)序列)混合使用
通過布爾型索引選取數(shù)組中的數(shù)據(jù),將總是創(chuàng)建數(shù)據(jù)的副本,即使返回一模一樣的數(shù)組也是如此。
注:python關(guān)鍵字and和or在布爾型數(shù)組中無效。
需要組合應(yīng)用多個布爾條件,使用&(和)、|(或)之類的布爾算術(shù)運算符即可。
通過布爾型數(shù)組設(shè)置值是一種經(jīng)常用到是手段。為了將data中的所有負(fù)值都設(shè)置為0,我們只需:data[data<0]=o
7.花式索引
花式索引(Fancy indexing)是一個NumPy術(shù)語,它指的是利用整數(shù)數(shù)組進(jìn)行索引。
- 一次傳入多個索引數(shù)組會有一點特別。它返回的是一個一維數(shù)組,其中的元素對應(yīng)各個索引元組。
注:有關(guān)reshape的知識將在第十二章中講解
In [108]:arr=np.arange(32).reshape((8,4))
In [109]:arr
out [109]:
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,30,31]])
In [110]:arr[[1,5,7,2],[0,3,1,2]]
Out [110]:array([4,23,29,10])
這個[110]索引,最終選出來的是元素(1,0)、(5,3)、(7,1)和(2,2)。
In [111]:arr[1,5,7,2][ : , [0,3,1,2]]
Out [111]:
array([[4,7,5,6,],
[20,23,21,22],
[28,31,29,30],
[8,11,9,10]])
另外一個辦法是使用np.ix_函數(shù),它可以將兩個一維整數(shù)數(shù)組轉(zhuǎn)換為一個用于選取方形區(qū)域的索引器:
In[112]:arr[np.ix_([1,7,5,2],[0,3,1,2])]
Out[112]:
array([[4,7,5,6,],
[20,23,21,22],
[28,31,29,30],
[8,11,9,10]])
- 注:花式索引跟切片不一樣,它總是將數(shù)據(jù)復(fù)制到新數(shù)組中。
8.數(shù)組轉(zhuǎn)置和軸對換
轉(zhuǎn)置(transpose)是重塑的一種特殊形式,它返回的是源數(shù)據(jù)的視圖(不會進(jìn)行任何復(fù)制操作)。數(shù)組不僅有(transpose),還有一個特殊的T屬性:
In[110]:arr=np.arange(15).reshape((3,5))
In[111]:arr
Out[110]:
array([[0,1,2,3,4],
[5,6,7,8,9,],
[10,11,12,13,14]])
In[112]:arr.T
Out[112]:
array([[0,5,10],
[1,6,11],
[2,7,12]
[3,8,13],
[4,9,14]])
在進(jìn)行矩陣計算時,經(jīng)常需要要到該操作,比如利用np.dot計算矩陣內(nèi)積XTX:
In[113]:arr=np.random.randn(6,3)
In[114]:np.dot(arr.T,arr)
Out[114]:
array([[2.584,1.8753,0.8888],
[1.8753,6.6636,0.3884],
[0.8888,0.3884,3.9781])
- 對于高維數(shù)組,transpose需要得到一個由軸編號組成元組才能對這些軸進(jìn)行轉(zhuǎn)置(比較費腦子)
In[115]:arr=np.arange(16)reshape((2,2,4))
In[116]:arr
Out[116]:
array([[[0,1,2,3],
[4,5,6,7]],
[[8,9,10,11],
[12,13,14,15]]])
In[117]:arr.transpose((1,0,2))
Out[117]:
array([[[0,1,2,3],
[8,9,10,11]],
[[4,5,6,7],
[12,13,14,15]]])
簡單的轉(zhuǎn)置可以使用.T,它其實就是軸對換而已;ndarry還有一個swapaxes方法,它需要接受一對軸編號。
In[118]:arr
Out[118]:
array([[[0,1,2,3],
[4,5,6,7]],
[[8,9,10,11],
[12,13,14,15]]])
In[119]:arr.swapaxes(1,2)
Out[119]:
array([[[0,4],
[1,5],
[2,6],
[3,7]],
[[8,12],
[9,13],
[10,14],
[11,15]]])
- swapaxes也是返回源數(shù)據(jù)的視圖(不會進(jìn)行任何復(fù)制操作)
二、通用函數(shù):快速的元素級數(shù)組函數(shù)
- 通用函數(shù)(即ufunc)是一種對ndarray中的數(shù)據(jù)執(zhí)行元素級運算的函數(shù)??梢詫⑵淇醋骱唵魏瘮?shù)(接受一個或多個標(biāo)量值,并產(chǎn)生一個或多個標(biāo)量值)的矢量化包裝器。
- 許多ufunc都是簡單的元素級變體,比如sqrt和exp
三、利用數(shù)組進(jìn)行數(shù)據(jù)處理
numpy數(shù)組可以將許多種數(shù)據(jù)處理任務(wù)表述為簡潔的數(shù)組表達(dá)式。用數(shù)組表達(dá)式代替循環(huán)的做法,通常被稱為矢量化。
1.將條件邏輯表述為數(shù)組運算
numpy.where函數(shù)是三元表達(dá)式 x if condntion else y 的矢量化版本
np.where的第二個和第三個參數(shù)不必是數(shù)組,他們都可以是標(biāo)量值。在數(shù)據(jù)分析工作中,where通常用于根據(jù)另外一個數(shù)組而產(chǎn)生一個新數(shù)組。
例:假如有一個由隨機(jī)數(shù)組成的矩陣,將所有正值替換為2,將所有負(fù)值替換為-2——np.where(arr>0,2,-2)
np.where(arr>0,2,arr)#只將正值設(shè)置為2.
- 傳遞給where的數(shù)組大小可以不相等,甚至可以時標(biāo)量值。
2.數(shù)學(xué)和統(tǒng)計方法
可以通過數(shù)組上的一組數(shù)學(xué)函數(shù)對整個數(shù)組或某個軸向的數(shù)據(jù)進(jìn)行統(tǒng)計計算。sum、mean、以及標(biāo)準(zhǔn)差std等聚合運算(aggregation,通常叫做約簡(reduction)),既可以當(dāng)做數(shù)組的實例方法調(diào)用,也可以當(dāng)做頂級NumPy函數(shù)使用。
- mean和sum這類的函數(shù)可以接受一個axis參數(shù)(用于計算該軸向上的統(tǒng)計值),最終結(jié)果是一個少一維數(shù)組。
- sum 對數(shù)組中全部或某軸向元素求和。零長度的數(shù)組的sum為0
- mean算術(shù)平均數(shù)。零長度數(shù)組的mean為NaN。
- std、var分別為標(biāo)準(zhǔn)差和方差,自由度可調(diào)(默認(rèn)為n)
- min、max最大值和最小值
- argmin、argmax分別為最小和最大元素的索引。
- cumsum所有元素的累計和
- cumpord所有元素的累計積
3.用于布爾型數(shù)組的方法
- 在上面這些方法中,布爾值會被強(qiáng)制轉(zhuǎn)化為1(true)和0(false),因此sum經(jīng)常被用來對布爾型數(shù)組中的True值計數(shù):
In[160]:arr =randn(100)
(arr>0).sum()#正值的數(shù)量 - 另外還有兩個方法any和all,他們對布爾型數(shù)組非常有用。any用于測試數(shù)組中是否存在一個或多個True,而all則檢查數(shù)組中所有值是否都是True
In[162]:bools=np.array([False,False,True,False])
In[163]:bools.any()
Out[163]:True
In[163]:bools.all()
Out[164]:False
4.排序
根python內(nèi)置的列表類型一樣,NumPy數(shù)組也可以通過sort方法就地排序
- 多維數(shù)組可以在任何一個軸上排序,只需將軸編號傳給sort即可。
- 頂級方法np.sort返回的是數(shù)組的已排序副本,而就地排序則會修改數(shù)組本身。計算數(shù)組分位數(shù)最簡單的辦法是對其進(jìn)行排序,然后選取特定位置的值。
5.唯一化以及其他的集合邏輯
NumPy提供了一些針對一維ndarray的基本集合運算。最常用的可能要數(shù)np.uniqe了, 它用于找出數(shù)組中的唯一值并返回已排序結(jié)果。
數(shù)組的集合運算
- unique(x)計算x中的唯一元素,并返回有序結(jié)果
- intersect1d(x,y)計算x和y中的公共元素,并返回有序結(jié)果
- union1d(x,y)計算x和y的并集,并返回有序結(jié)果
- in1d(x,y)得到一個表示“x的元素是否包含于y”的布爾型數(shù)組
- setdiff1d(x,y)集合的差,即元素在X中且不在y中
- setxor1d(x,y)集合的對稱差,即存在于一個數(shù)組中但不同時存在于兩個數(shù)組中的元素。
四、用于數(shù)組的文件輸入輸出
1.將數(shù)組以二進(jìn)制格式保存到磁盤
np.save和np.load是讀寫磁盤數(shù)組數(shù)據(jù)的兩個主要函數(shù)。默認(rèn)情況下,數(shù)組是以未壓縮的原始二進(jìn)制格式保存在擴(kuò)展名為.npy的文件中的。
In[183]:arr=np.arange(10)
In[184]:np.save('some_array',arr)
- 如果文件路徑末尾沒有擴(kuò)展名.npy,則該擴(kuò)展名會被自動加上。然后具可以通過np.load讀取磁盤上的數(shù)組:
In[185]:np.load('some_array.npy')
Out[185]:array([0,1,2,3,4,5,6,7,8,9]) - 通過np.savez可以將多個數(shù)組保存到一個壓縮文件中,將數(shù)組以關(guān)鍵字參數(shù)的形式傳入即可
2.存取文本文件
有時,我們需要用np.loadtxt或更為專門化的np.genfromtxt將數(shù)據(jù)加載到普通的NumPy數(shù)組中。
五、線性代數(shù)
線性代數(shù)(如矩陣乘法、矩陣分解、行列式以及其他方陣數(shù)學(xué)等)是任何數(shù)組庫的重要組成部分。NumPy提供了一個用于矩陣乘法的dot函數(shù)(既是一個數(shù)組方法也是NumPy命名空間的一個函數(shù))
- dot矩陣乘法
- trane計算對角線元素的和
- deg計算矩陣行列式
- eig計算方陣的本征值和本征向量
- inv 計算方陣的逆
六、隨機(jī)數(shù)生成
numpy.random模塊對Python內(nèi)置的random進(jìn)行了補(bǔ)充,增加了一些用于高效生成多種概率分布的樣本值的函數(shù)。
- 用normal得到一個標(biāo)準(zhǔn)正態(tài)分布的4*4樣本數(shù)組: