NumPy(Numerical Python的簡(jiǎn)稱(chēng))是高性能科學(xué)計(jì)算和數(shù)據(jù)分析的基礎(chǔ)包。其部分功能包括:
- ndarray ,一個(gè)具有矢量算術(shù)運(yùn)算和復(fù)雜廣播能力的快速且節(jié)省空間的多維數(shù)組驯遇。
- 用于對(duì)整組數(shù)據(jù)進(jìn)行快速運(yùn)算的標(biāo)準(zhǔn)數(shù)學(xué)函數(shù)(無(wú)需編寫(xiě)循環(huán))
- 用于讀寫(xiě)磁盤(pán)數(shù)據(jù)的工具以及用于操作內(nèi)存內(nèi)存映射文件的工具。
- 線性代數(shù)羡疗、隨機(jī)數(shù)生成以及傅里葉變換功能这难。
- 用于集成有C++,C造垛,F(xiàn)ortran等編程語(yǔ)言的代碼工具魔招。
對(duì)于大部分?jǐn)?shù)據(jù)分析應(yīng)用而言,我最關(guān)注的功能主要集中在:
- 用于數(shù)據(jù)整理和清理五辽、子集構(gòu)造和過(guò)濾办斑、轉(zhuǎn)換等快速的矢量化數(shù)組運(yùn)算。
- 通常的數(shù)組加法杆逗,如排序乡翅、唯一化、集合運(yùn)算等罪郊。
- 高效的描述統(tǒng)計(jì)和數(shù)據(jù)聚合/摘要運(yùn)算蠕蚜。
- 用于異構(gòu)數(shù)據(jù)集的合并/連接運(yùn)算的數(shù)據(jù)對(duì)齊和關(guān)系型數(shù)據(jù)運(yùn)算
- 將條件邏輯表述為數(shù)組表達(dá)式(而不是帶有if-elif-else分支的循環(huán))
- 數(shù)據(jù)的分組運(yùn)算(集合、轉(zhuǎn)換悔橄、函數(shù)應(yīng)用等)
一靶累、NumPy的ndarray:一組多維數(shù)組對(duì)象
NumPy最重要的一個(gè)特點(diǎn)就是:其N(xiāo)維數(shù)組對(duì)象(即ndarray)腺毫,該對(duì)象是一個(gè)快速而靈活的大數(shù)據(jù)集容器,可以利用這種數(shù)組對(duì)整塊數(shù)據(jù)執(zhí)行一些數(shù)學(xué)運(yùn)算挣柬。
ndarray是一個(gè)通用的同構(gòu)數(shù)據(jù)多維容器潮酒,也就是說(shuō),其中的所有元素必須是相同類(lèi)型的邪蛔。每個(gè)數(shù)組都有一個(gè)shape(一個(gè)表示各維度大小的元組)和一個(gè)dtype(一個(gè)用于說(shuō)明數(shù)據(jù)類(lèi)型的對(duì)象)
1.創(chuàng)建ndarray
創(chuàng)建數(shù)組最簡(jiǎn)單的方法就是使用array函數(shù)急黎。它接受一切序列型的對(duì)象(包括其他數(shù)組),然后產(chǎn)生一個(gè)新的含有傳入數(shù)據(jù)的NumPy的數(shù)組侧到。
嵌套序列(比如由一組等長(zhǎng)列表組成的列表)勃教,將會(huì)被轉(zhuǎn)換成一個(gè)多維數(shù)組。
注:np.array會(huì)嘗試為新建的這個(gè)數(shù)組推斷出一個(gè)較為合適的數(shù)據(jù)類(lèi)型匠抗。數(shù)據(jù)類(lèi)型保存在一個(gè)特殊的dtype對(duì)象中故源。
除了np.array之外,還有一些函數(shù)也可以新建數(shù)組戈咳。比如zeros和ones分別可以創(chuàng)建指定長(zhǎng)度或形狀的全0或全1數(shù)組心软。empty可以創(chuàng)建一個(gè)沒(méi)有任何具體值的數(shù)組。要用這些方法創(chuàng)建多維數(shù)組著蛙,只需傳入一個(gè)表示形狀的元組即可删铃。
arange 是python內(nèi)置函數(shù)range的數(shù)組版.
由于NumPy關(guān)注的是數(shù)值計(jì)算,因此踏堡,如果沒(méi)有特別指定猎唁,數(shù)據(jù)類(lèi)型基本都是fioat64(浮點(diǎn)數(shù))
array 將輸入數(shù)據(jù)(列表、元組顷蟆、數(shù)組或其他序列類(lèi)型)轉(zhuǎn)換為ndarry诫隅。要么推斷出dtype,要么顯示指定dtype帐偎。默認(rèn)直接復(fù)制輸入數(shù)據(jù)逐纬。
asarray 將輸入轉(zhuǎn)化為ndarray,如果輸入本身就是一個(gè)ndarray就不進(jìn)行復(fù)制削樊。
arange類(lèi)似內(nèi)置的range豁生,但返回的是一個(gè)ndarray,而不是列表漫贞。
ones甸箱、ones_like根據(jù)指定形狀和dtype創(chuàng)建一個(gè)全1數(shù)組。 ones_like以另一個(gè)數(shù)組為參數(shù)迅脐,并根據(jù)其形狀和dtype創(chuàng)建一個(gè)全1數(shù)組芍殖。
zeros、zeros_like類(lèi)似于ones谴蔑、ones_like豌骏,只不過(guò)產(chǎn)生的是全0數(shù)組而已龟梦。
eye、identity創(chuàng)建一個(gè)正方的N*N單位矩陣(對(duì)角線為1肯适,其余為0)
2.ndarray的數(shù)據(jù)類(lèi)型
dtype(數(shù)據(jù)類(lèi)型)是一個(gè)特殊的對(duì)象变秦,它含有ndarray將一塊內(nèi)存解釋為特定數(shù)據(jù)類(lèi)型所需的信息成榜。
數(shù)值形dtype的命名方式相同:一個(gè)類(lèi)型名(如float或int)框舔,后面跟一個(gè)用于表示各元素位長(zhǎng)的數(shù)字。
- 可以通過(guò)ndarray的astype方法顯式地轉(zhuǎn)化其dtype赎婚。
- 注:調(diào)用astype無(wú)論如何都會(huì)創(chuàng)建一個(gè)新的數(shù)組(原始數(shù)據(jù)的一份拷貝)刘绣,即使新dtype跟老dtype相同也是如此。
3.數(shù)組和標(biāo)量之間的運(yùn)算
數(shù)組很重要挣输,因?yàn)樗鼓悴挥镁帉?xiě)循環(huán)即可對(duì)數(shù)據(jù)執(zhí)行批量運(yùn)算纬凤。這通常就叫做矢量化。大小相等的數(shù)組之間的任何算術(shù)運(yùn)算都會(huì)將運(yùn)算應(yīng)用到元素級(jí)撩嚼。
同樣停士,數(shù)組與標(biāo)量的算術(shù)運(yùn)算也會(huì)將那個(gè)標(biāo)量值傳播到各個(gè)元素。
不同大小的數(shù)組之間的運(yùn)算叫做廣播
4.基本的索引和切片
NumPy數(shù)組的索引是一個(gè)內(nèi)容豐富的主題完丽,因?yàn)檫x取數(shù)據(jù)子集或單個(gè)元素的方式有限多恋技。
當(dāng)你將一個(gè)標(biāo)量值賦值給一個(gè)切片時(shí)(如arr[5:8]=12),該值會(huì)自動(dòng)傳播到整個(gè)選區(qū)逻族。跟列表最重要的區(qū)別在于蜻底,數(shù)組切片是原始數(shù)組的視圖。這意味著數(shù)據(jù)不會(huì)被復(fù)制聘鳞,視圖上的任何修改都會(huì)直接反映到源數(shù)組上薄辅。
注:如果你想得到的是ndarray切片的一份副本而非視圖,就需要顯式地進(jìn)行復(fù)制操作抠璃,例如:arr[5:8].copy()
對(duì)于高維度數(shù)組站楚,能做的事情更多。在一個(gè)二維數(shù)組中搏嗡,各索引位置上的元素不再是標(biāo)量而是一維數(shù)組窿春。
可以對(duì)各個(gè)元素進(jìn)行遞歸訪問(wèn),但這樣需要做的事情有點(diǎn)多彻况∷可以傳入一個(gè)以逗號(hào)隔開(kāi)的索引列表來(lái)獲取單個(gè)元素。也就是說(shuō)纽甘,下面兩種方式是等價(jià)的:arr2d[0][2]
arr2d[0,2]
在多維數(shù)組中良蛮,如果省略了后面的索引,則返回對(duì)象會(huì)是一個(gè)維度低一點(diǎn)的ndarray(它含有高一級(jí)維度上的所有數(shù)據(jù))
5.切片索引
ndarray的切片語(yǔ)法跟Python列表這樣的一維對(duì)象差不多
高維度對(duì)象的花樣更多悍赢,你可以在一個(gè)或多個(gè)軸上進(jìn)行切片决瞳,也可以跟整數(shù)索引混合使用货徙。它是沿著第0軸(即第一個(gè)軸切片的)。也就是說(shuō)皮胡,切片是沿著一個(gè)軸向選取元素的痴颊,可以一次傳入多個(gè)切片,就像傳入多個(gè)索引那樣屡贺。
arr2d[ :2,1: ]注:括號(hào)外面的“維度”是一維蠢棱、二維、三維甩栈、四維之類(lèi)的意思泻仙,而括號(hào)里面的應(yīng)該理解為“軸”。
注:“只有冒號(hào)”表示選取整個(gè)軸
6.布爾型索引
布爾型數(shù)組的長(zhǎng)度必須跟被索引的軸的長(zhǎng)度一致量没。此外玉转,還可以將布爾型數(shù)組跟切片、整數(shù)(或整數(shù)序列)混合使用
通過(guò)布爾型索引選取數(shù)組中的數(shù)據(jù)殴蹄,將總是創(chuàng)建數(shù)據(jù)的副本究抓,即使返回一模一樣的數(shù)組也是如此。
注:python關(guān)鍵字and和or在布爾型數(shù)組中無(wú)效袭灯。
需要組合應(yīng)用多個(gè)布爾條件刺下,使用&(和)、|(或)之類(lèi)的布爾算術(shù)運(yùn)算符即可妓蛮。
通過(guò)布爾型數(shù)組設(shè)置值是一種經(jīng)常用到是手段怠李。為了將data中的所有負(fù)值都設(shè)置為0,我們只需:data[data<0]=o
7.花式索引
花式索引(Fancy indexing)是一個(gè)NumPy術(shù)語(yǔ)蛤克,它指的是利用整數(shù)數(shù)組進(jìn)行索引捺癞。
- 一次傳入多個(gè)索引數(shù)組會(huì)有一點(diǎn)特別。它返回的是一個(gè)一維數(shù)組构挤,其中的元素對(duì)應(yīng)各個(gè)索引元組髓介。
注:有關(guān)reshape的知識(shí)將在第十二章中講解
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])
這個(gè)[110]索引,最終選出來(lái)的是元素(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]])
另外一個(gè)辦法是使用np.ix_函數(shù),它可以將兩個(gè)一維整數(shù)數(shù)組轉(zhuǎn)換為一個(gè)用于選取方形區(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)置和軸對(duì)換
轉(zhuǎn)置(transpose)是重塑的一種特殊形式,它返回的是源數(shù)據(jù)的視圖(不會(huì)進(jìn)行任何復(fù)制操作)洒沦。數(shù)組不僅有(transpose)豹绪,還有一個(gè)特殊的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ì)算時(shí),經(jīng)常需要要到該操作申眼,比如利用np.dot計(jì)算矩陣內(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])
- 對(duì)于高維數(shù)組蝉衣,transpose需要得到一個(gè)由軸編號(hào)組成元組才能對(duì)這些軸進(jìn)行轉(zhuǎn)置(比較費(fèi)腦子)
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]]])
簡(jiǎn)單的轉(zhuǎn)置可以使用.T,它其實(shí)就是軸對(duì)換而已巷蚪;ndarry還有一個(gè)swapaxes方法病毡,它需要接受一對(duì)軸編號(hào)。
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ù)的視圖(不會(huì)進(jìn)行任何復(fù)制操作)
二屁柏、通用函數(shù):快速的元素級(jí)數(shù)組函數(shù)
- 通用函數(shù)(即ufunc)是一種對(duì)ndarray中的數(shù)據(jù)執(zhí)行元素級(jí)運(yùn)算的函數(shù)啦膜。可以將其看作簡(jiǎn)單函數(shù)(接受一個(gè)或多個(gè)標(biāo)量值前联,并產(chǎn)生一個(gè)或多個(gè)標(biāo)量值)的矢量化包裝器功戚。
- 許多ufunc都是簡(jiǎn)單的元素級(jí)變體,比如sqrt和exp
三似嗤、利用數(shù)組進(jìn)行數(shù)據(jù)處理
numpy數(shù)組可以將許多種數(shù)據(jù)處理任務(wù)表述為簡(jiǎn)潔的數(shù)組表達(dá)式。用數(shù)組表達(dá)式代替循環(huán)的做法届宠,通常被稱(chēng)為矢量化烁落。
1.將條件邏輯表述為數(shù)組運(yùn)算
numpy.where函數(shù)是三元表達(dá)式 x if condntion else y 的矢量化版本
np.where的第二個(gè)和第三個(gè)參數(shù)不必是數(shù)組,他們都可以是標(biāo)量值豌注。在數(shù)據(jù)分析工作中伤塌,where通常用于根據(jù)另外一個(gè)數(shù)組而產(chǎn)生一個(gè)新數(shù)組。
例:假如有一個(gè)由隨機(jī)數(shù)組成的矩陣轧铁,將所有正值替換為2每聪,將所有負(fù)值替換為-2——np.where(arr>0,2,-2)
np.where(arr>0,2,arr)#只將正值設(shè)置為2.
- 傳遞給where的數(shù)組大小可以不相等,甚至可以時(shí)標(biāo)量值齿风。
2.數(shù)學(xué)和統(tǒng)計(jì)方法
可以通過(guò)數(shù)組上的一組數(shù)學(xué)函數(shù)對(duì)整個(gè)數(shù)組或某個(gè)軸向的數(shù)據(jù)進(jìn)行統(tǒng)計(jì)計(jì)算药薯。sum、mean救斑、以及標(biāo)準(zhǔn)差std等聚合運(yùn)算(aggregation童本,通常叫做約簡(jiǎn)(reduction)),既可以當(dāng)做數(shù)組的實(shí)例方法調(diào)用脸候,也可以當(dāng)做頂級(jí)NumPy函數(shù)使用穷娱。
- mean和sum這類(lèi)的函數(shù)可以接受一個(gè)axis參數(shù)(用于計(jì)算該軸向上的統(tǒng)計(jì)值),最終結(jié)果是一個(gè)少一維數(shù)組运沦。
- sum 對(duì)數(shù)組中全部或某軸向元素求和泵额。零長(zhǎng)度的數(shù)組的sum為0
- mean算術(shù)平均數(shù)。零長(zhǎng)度數(shù)組的mean為NaN携添。
- std嫁盲、var分別為標(biāo)準(zhǔn)差和方差,自由度可調(diào)(默認(rèn)為n)
- min薪寓、max最大值和最小值
- argmin亡资、argmax分別為最小和最大元素的索引澜共。
- cumsum所有元素的累計(jì)和
- cumpord所有元素的累計(jì)積
3.用于布爾型數(shù)組的方法
- 在上面這些方法中,布爾值會(huì)被強(qiáng)制轉(zhuǎn)化為1(true)和0(false),因此sum經(jīng)常被用來(lái)對(duì)布爾型數(shù)組中的True值計(jì)數(shù):
In[160]:arr =randn(100)
(arr>0).sum()#正值的數(shù)量 - 另外還有兩個(gè)方法any和all锥腻,他們對(duì)布爾型數(shù)組非常有用嗦董。any用于測(cè)試數(shù)組中是否存在一個(gè)或多個(gè)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)置的列表類(lèi)型一樣瘦黑,NumPy數(shù)組也可以通過(guò)sort方法就地排序
- 多維數(shù)組可以在任何一個(gè)軸上排序京革,只需將軸編號(hào)傳給sort即可。
- 頂級(jí)方法np.sort返回的是數(shù)組的已排序副本幸斥,而就地排序則會(huì)修改數(shù)組本身匹摇。計(jì)算數(shù)組分位數(shù)最簡(jiǎn)單的辦法是對(duì)其進(jìn)行排序,然后選取特定位置的值甲葬。
5.唯一化以及其他的集合邏輯
NumPy提供了一些針對(duì)一維ndarray的基本集合運(yùn)算廊勃。最常用的可能要數(shù)np.uniqe了, 它用于找出數(shù)組中的唯一值并返回已排序結(jié)果经窖。
數(shù)組的集合運(yùn)算
- unique(x)計(jì)算x中的唯一元素坡垫,并返回有序結(jié)果
- intersect1d(x,y)計(jì)算x和y中的公共元素,并返回有序結(jié)果
- union1d(x,y)計(jì)算x和y的并集画侣,并返回有序結(jié)果
- in1d(x,y)得到一個(gè)表示“x的元素是否包含于y”的布爾型數(shù)組
- setdiff1d(x,y)集合的差冰悠,即元素在X中且不在y中
- setxor1d(x,y)集合的對(duì)稱(chēng)差,即存在于一個(gè)數(shù)組中但不同時(shí)存在于兩個(gè)數(shù)組中的元素配乱。
四溉卓、用于數(shù)組的文件輸入輸出
1.將數(shù)組以二進(jìn)制格式保存到磁盤(pán)
np.save和np.load是讀寫(xiě)磁盤(pán)數(shù)組數(shù)據(jù)的兩個(gè)主要函數(shù)。默認(rèn)情況下搬泥,數(shù)組是以未壓縮的原始二進(jìn)制格式保存在擴(kuò)展名為.npy的文件中的桑寨。
In[183]:arr=np.arange(10)
In[184]:np.save('some_array',arr)
- 如果文件路徑末尾沒(méi)有擴(kuò)展名.npy,則該擴(kuò)展名會(huì)被自動(dòng)加上佑钾。然后具可以通過(guò)np.load讀取磁盤(pán)上的數(shù)組:
In[185]:np.load('some_array.npy')
Out[185]:array([0,1,2,3,4,5,6,7,8,9]) - 通過(guò)np.savez可以將多個(gè)數(shù)組保存到一個(gè)壓縮文件中西疤,將數(shù)組以關(guān)鍵字參數(shù)的形式傳入即可
2.存取文本文件
有時(shí),我們需要用np.loadtxt或更為專(zhuān)門(mén)化的np.genfromtxt將數(shù)據(jù)加載到普通的NumPy數(shù)組中休溶。
五代赁、線性代數(shù)
線性代數(shù)(如矩陣乘法、矩陣分解兽掰、行列式以及其他方陣數(shù)學(xué)等)是任何數(shù)組庫(kù)的重要組成部分芭碍。NumPy提供了一個(gè)用于矩陣乘法的dot函數(shù)(既是一個(gè)數(shù)組方法也是NumPy命名空間的一個(gè)函數(shù))
- dot矩陣乘法
- trane計(jì)算對(duì)角線元素的和
- deg計(jì)算矩陣行列式
- eig計(jì)算方陣的本征值和本征向量
- inv 計(jì)算方陣的逆
六、隨機(jī)數(shù)生成
numpy.random模塊對(duì)Python內(nèi)置的random進(jìn)行了補(bǔ)充孽尽,增加了一些用于高效生成多種概率分布的樣本值的函數(shù)窖壕。
- 用normal得到一個(gè)標(biāo)準(zhǔn)正態(tài)分布的4*4樣本數(shù)組: