簡單整理了NumPy的一些特性,參考的是 《利用Python進行數(shù)據(jù)分析》( Wes McKinney 著),NumPy官方文檔,菜鳥教程。
NumPy(Numerical Python的簡稱)是高性能科學(xué)計算和數(shù)據(jù)分析的基礎(chǔ)包。而且NumPy會提供一個簡單易用的C API,所以很容易把數(shù)據(jù)傳遞給由低級語言編寫的外部庫,外部庫也能以NumPy數(shù)組的形式將數(shù)據(jù)返回給Python。
本文章的目錄如下:
- ndarray對象
- NumPy數(shù)據(jù)類型
- 數(shù)組屬性
- 切片和索引
- 運算——與標(biāo)量之間 & 與數(shù)組之間(廣播)
- 函數(shù)
- 數(shù)組操作
ndarray
NumPy的ndarray是一個n維數(shù)組對象,是一系列同類型數(shù)據(jù)的集合,以0為下標(biāo)開始元素的索引。
可以利用這種對象對整塊數(shù)據(jù)進行數(shù)學(xué)運算,語法跟標(biāo)量之間的運算一樣。
ndarray由以下內(nèi)容組成:
- 一個指向數(shù)據(jù)的指針。
- 每個數(shù)組的
shape屬性表示各維度大小,是表示數(shù)組形狀的元組。 -
dtype屬性說明數(shù)組類型的對象。 - 一個跨度元組
stride,其中的整數(shù)指為了前進到當(dāng)前維度下一個元素需要‘跨過’的字節(jié)數(shù)。
內(nèi)部結(jié)構(gòu)如下:
image
創(chuàng)建一個ndarray的方法是用NumPy中的array函數(shù):
np.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
參數(shù)參考這里。
它接收一切序列型的對象(包括其他數(shù)組),然后產(chǎn)生一個新的含有傳入數(shù)據(jù)的NumPy數(shù)組。
嵌套序列將會被轉(zhuǎn)換為一個多維數(shù)組。
還有一些函數(shù)可以新建數(shù)組,比如zeros和ones分別可以創(chuàng)建指定長度或形狀的全0或全1數(shù)組。empty函數(shù)會返回一些未初始化的垃圾值。
asarray函數(shù)講輸入轉(zhuǎn)換為ndarray。
ones_like, zeros_like, empty_like以另一個數(shù)組為參數(shù),并根據(jù)其形狀和dtype創(chuàng)建一個全1數(shù)組/全0數(shù)組/empty數(shù)組。
eye, identity創(chuàng)建一個正方的N??N矩陣。(對角線為1,其余為0)
如果沒有特別指定,數(shù)據(jù)類型基本都是float64(浮點數(shù))。
np.zeros(10)
np.zeros((3,6))
np.empty((2,3,2))
arange 函數(shù)是python內(nèi)置函數(shù)range的數(shù)組版,會生成相應(yīng)的ndarray。
arr=np.arange(10)
arr
>array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
若要檢查數(shù)組中的數(shù)據(jù)類型,可以用一個超類結(jié)合`np.issubdtype'函數(shù)來操作。
np.issubdtype(array1,np.integer)
np.issubdtype(array2,np.floating)
np.float64.mro() #查看所有的父類
NumPy數(shù)據(jù)類型
dtype(數(shù)據(jù)類型)是一類特殊的對象,它含有ndarray將一塊內(nèi)存解釋為特定數(shù)據(jù)類型所需的信息。它是NumPy如此強大和靈活的原因之一。數(shù)值型dtype的命名方式相同:一個類型名+一個用于表示各元素位長的數(shù)字(如float64)。
NumPy支持的數(shù)據(jù)類型比Python內(nèi)置的類型要多很多,基本上可以和C語言的數(shù)據(jù)類型對應(yīng)上。
可以通過ndarray的astype方法顯式地轉(zhuǎn)換其dtype:
float_arr = arr.astype(np.float64)
調(diào)用astype會創(chuàng)建出一個新的數(shù)組(原始數(shù)據(jù)的一份拷貝)。
數(shù)組屬性
NumPy 數(shù)組的維數(shù)稱為秩(rank),一維數(shù)組的秩為 1,二維數(shù)組的秩為 2,以此類推。
在 NumPy中,每一個線性的數(shù)組稱為是一個軸(axis),也就是維度(dimensions)。比如說,二維數(shù)組相當(dāng)于是兩個一維數(shù)組,其中第一個一維數(shù)組中每個元素又是一個一維數(shù)組。所以一維數(shù)組就是 NumPy 中的軸(axis),第一個軸相當(dāng)于是底層數(shù)組,第二個軸是底層數(shù)組里的數(shù)組。而軸的數(shù)量——秩,就是數(shù)組的維數(shù)。
很多時候可以聲明 axis。axis=0,表示沿著第 0 軸進行操作,即對每一列進行操作;axis=1,表示沿著第1軸進行操作,即對每一行進行操作。
ndarray.ndim 用于返回數(shù)組的維數(shù),等于秩。
a = np.arange(24)
print (a.ndim)
>1
ndarray.shape 表示數(shù)組的維度,返回一個元組,這個元組的長度就是維度的數(shù)目,即 ndim 屬性(秩)。比如,一個二維數(shù)組,其維度表示"行數(shù)"和"列數(shù)"。ndarray.shape 也可以用于調(diào)整數(shù)組大小。
a = np.array([[1,2,3],[4,5,6]])
print (a.shape)
> (2, 3)
切片和索引
Numpy數(shù)組和python list的區(qū)別:數(shù)組切片是原始數(shù)據(jù)的視圖!
這意味著數(shù)據(jù)不會被復(fù)制,視圖上做任何修改都會直接反映到源數(shù)組上。
若要復(fù)制,則需要顯式地進行copy操作:如arr[5:8].copy()。
對于高維度數(shù)組,可以進行遞歸訪問。如 arr[0][2] or arr[0,2]。
切片索引
ndarray的切片語法跟Python的列表語法差不多。
注意:使用兩個參數(shù),如 [2:7],那么則提取兩個索引之間的項,不包括停止索引!
import numpy as np
a = np.arange(10)
b = a[2:7:2] # 從索引 2 開始到索引 7 停止,間隔為 2
print(b)
>[2 4 6]
高維度的對象花樣更多,可以在一個或多個軸上進行切片,也可以跟整數(shù)索引混合使用。
arr2d [:2,1:] #沿著第一,第二個軸切片
arr2d [:,2] #只有冒號表示選取整個軸
布爾型索引
在NumPy當(dāng)中,數(shù)組的比較運算也是矢量化的,所以數(shù)組與字符串的比較會產(chǎn)生一個布爾型數(shù)組。
布爾型數(shù)組可以直接用于數(shù)組索引,但是長度必須跟被索引的長度一致。也可以與其他切片方式混合使用。
可以通過!= or -來得到相反的值。
注意:
- 通過布爾型索引選取數(shù)組中的數(shù)據(jù),將總是創(chuàng)建數(shù)據(jù)的副本!
- Python的關(guān)鍵字and和or在布爾型數(shù)組當(dāng)中無效。如果需要組合多種運算條件,使用&,|等運算符。
花式索引(Fancy Indexing)
指的是利用整數(shù)數(shù)組進行索引。
花式索引根據(jù)索引數(shù)組的值作為目標(biāo)數(shù)組的某個軸的下標(biāo)來取值。對于使用一維整型數(shù)組作為索引,如果目標(biāo)是一維數(shù)組,那么索引的結(jié)果就是對應(yīng)位置的元素;如果目標(biāo)是二維數(shù)組,那么就是對應(yīng)下標(biāo)的行。
花式索引跟切片不一樣,它總是將數(shù)據(jù)復(fù)制到新數(shù)組中。
np.ix_函數(shù)將證書數(shù)組轉(zhuǎn)換為一個用于選取方形區(qū)域的索引器。
import numpy as np
# 一次傳入多個索引數(shù)組會有點特別
x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0,1,2], [0,1,0]] #以下實例獲取數(shù)組中(0,0),(1,1)和(2,0)位置處的元素。
print (y)
> [1 4 5]
x=np.arange(32).reshape((8,4))
x
>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]])
print (x[np.ix_([1,5,7,2],[0,3,1,2])])
>[[ 4 7 5 6]
[20 23 21 22]
[28 31 29 30]
[ 8 11 9 10]]
運算——與標(biāo)量之間 & 與數(shù)組之間(廣播)
與標(biāo)量之間:
數(shù)組與標(biāo)量的算術(shù)運算會將那個標(biāo)量值傳播到各個元素。
與數(shù)組之間:
大小相等的數(shù)組之間的算術(shù)運算會將運算應(yīng)用到元素級。
如果兩個數(shù)組 a 和 b 形狀相同,即滿足 a.shape == b.shape,那么 a*b 的結(jié)果就是 a 與 b 數(shù)組對應(yīng)位相乘。這要求維數(shù)相同,且各維度的長度相同。
不同大小的數(shù)組之間的運算叫做廣播(Broadcast)。
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([1,2,3])
print(a + b)
>[[ 1 2 3]
[11 12 13]
[21 22 23]
[31 32 33]]
廣播的規(guī)則:
讓所有輸入數(shù)組都向其中形狀最長的數(shù)組看齊,形狀中不足的部分都通過在前面加 1 補齊。
輸出數(shù)組的形狀是輸入數(shù)組形狀的各個維度上的最大值。
如果輸入數(shù)組的某個維度和輸出數(shù)組的對應(yīng)維度的長度相同或者其長度為 1 時,這個數(shù)組能夠用來計算,否則出錯。
當(dāng)輸入數(shù)組的某個維度的長度為 1 時,沿著此維度運算時都用此維度上的第一組值。
簡單理解:對兩個數(shù)組,分別比較他們的每一個維度(若其中一個數(shù)組沒有當(dāng)前維度則忽略),滿足:
數(shù)組擁有相同形狀。
當(dāng)前維度的值相等。
當(dāng)前維度的值有一個是 1。
若條件不滿足,拋出 "ValueError: frames are not aligned" 異常。
廣播的原則:如果兩個數(shù)組的trailing dimension(從末尾開始算起的維度)的軸長度相符或其中一方為1,則認(rèn)為他們是廣播兼容的。
函數(shù)
轉(zhuǎn)置.T屬性返回源數(shù)據(jù)的視圖。數(shù)組還有transpose方法, swapaxes方法。
通用函數(shù)是對ndarray中的數(shù)據(jù)執(zhí)行元素級運算的函數(shù)。
- 算數(shù)函數(shù):包含簡單的加減乘除: add(),subtract(),multiply() 和 divide()。
- 數(shù)學(xué)函數(shù):NumPy 包含大量的各種數(shù)學(xué)運算的函數(shù),包括三角函數(shù),算術(shù)運算的函數(shù),復(fù)數(shù)處理函數(shù)等。
- 字符串函數(shù):
這些函數(shù)在字符數(shù)組類(numpy.char)中定義。詳見http://www.runoob.com/numpy/numpy-string-functions.html。 - 統(tǒng)計函數(shù):
numpy.amin()用于計算數(shù)組中的元素沿指定軸的最小值。
numpy.amax()用于計算數(shù)組中的元素沿指定軸的最大值。
numpy.ptp()函數(shù)計算數(shù)組中元素最大值與最小值的差(最大值 - 最小值)。
numpy.percentile()百分位數(shù)是統(tǒng)計中使用的度量,表示小于這個值的觀察值的百分比。
numpy.median()函數(shù)用于計算數(shù)組 a 中元素的中位數(shù)(中值)
numpy.mean()函數(shù)返回數(shù)組中元素的算術(shù)平均值。 如果提供了軸,則沿其計算。
numpy.average()函數(shù)根據(jù)在另一個數(shù)組中給出的各自的權(quán)重計算數(shù)組中元素的加權(quán)平均值。
標(biāo)準(zhǔn)差std= sqrt(mean((x - x.mean())2)) 標(biāo)準(zhǔn)差是方差的算術(shù)平方根。
var統(tǒng)計中的方差(樣本方差)是每個樣本值與全體樣本值的平均數(shù)之差的平方值的平均數(shù),即 mean((x - x.mean()) 2)。 - 排序/條件篩選函數(shù):
numpy.sort() 函數(shù)返回輸入數(shù)組的排序副本。函數(shù)格式如下:
numpy.sort(a, axis, kind, order)
a: 要排序的數(shù)組
axis: 沿著它排序數(shù)組的軸,如果沒有數(shù)組會被展開,沿著最后的軸排序, axis=0 按列排序,axis=1 按行排序
kind: 默認(rèn)為'quicksort'(快速排序)
order: 如果數(shù)組包含字段,則是要排序的字段
- 其他:
unique(): 計算唯一元素并返回有序結(jié)果
union1d(x,y): 計算并集并返回有序結(jié)果
intersect1d(x,y): 計算公共元素并返回有序結(jié)果 - NumPy 還有一系列與線性代數(shù)相關(guān)的函數(shù)。
數(shù)組操作
可以用reshape函數(shù)來修改數(shù)組的形狀,傳入一個表示新形狀的元組就能實現(xiàn)該目的。其中,-1表示該維度的大小由數(shù)據(jù)本身推斷而來。
將多維數(shù)組轉(zhuǎn)換為一維數(shù)組的方法有flatten(返回數(shù)據(jù)的副本,不影響原數(shù)組)ravel(返回展開數(shù)組)。
默認(rèn)情況下,NumPy數(shù)組是按行優(yōu)先順序創(chuàng)建的。
- 數(shù)組的鏈接和拆分:
numpy.condatenate可以按指定軸將一個由數(shù)組組成的序列(如元組,列表等)連接到一起。還可以設(shè)置axis。
對于常見的連接操作,NumPy還提供了一些比較方便的方法,比如np.vstackandnp.hstack。
與此相反,split用于將一個數(shù)組沿指定軸拆分成多個數(shù)組。 - 元素的重復(fù)操作
可以用repeat函數(shù)來實現(xiàn)。
如果傳入的是一個整數(shù),則可以將各個元素重復(fù)一定次數(shù)。
若傳入的是一組整數(shù),每個元素重復(fù)的次數(shù)不同。
對于多維數(shù)組,還可以讓它們沿指定軸重復(fù)。需要注意的是,如果沒有設(shè)置軸向,數(shù)組會被扁平化。
arr=np.arange(3)
arr.repeat(3)
> array([0,0,0,1,1,1,2,2,2])
arr.repeat([2,3,4])
> array([0,0,1,1,1,2,2,2,2])
tile函數(shù)的功能是沿指定軸堆疊數(shù)組的副本,像鋪瓷磚一樣。
第二個參數(shù)是瓷磚的數(shù)量,也可以是一個表示“鋪設(shè)”布局的元組。
-
take和put是花式索引的等價函數(shù),也可以獲取和設(shè)置數(shù)組子集。
