一.通用函數:快速的元素級數組函數
通用函數(ufunc)是一種對ndarray中的數據執行元素級運算的函數。我們可以將其看作簡單函數(接受一個或多個標量,並產生一個或多個標量)的矢量化包裝器。
許多通用函數都是簡單的元素級變體,如sqrt和exp:
import numpy as np arr=np.arange(10) print(np.sqrt(arr)) ======================================== [0. 1. 1.41421356 1.73205081 2. 2.23606798 2.44948974 2.64575131 2.82842712 3. ] ======================================== print(np.exp(arr)) ======================================== [1.00000000e+00 2.71828183e+00 7.38905610e+00 2.00855369e+01 5.45981500e+01 1.48413159e+02 4.03428793e+02 1.09663316e+03 2.98095799e+03 8.10308393e+03] ========================================
下表列出了常用的一元ufunc和二元ufunc
一元ufunc
函數 |
說明 |
abs、fbs |
計算整數、浮點數或復數的絕對值。對於非復數值,可以使用更快的fbs |
sqrt |
計算各元素的平方根,相當於arr**0.5 |
square |
計算各元素的平方,相當於arr**2 |
exp |
計算各元素的指數e |
log、log10、log2、log1p | 分別為自然對數(底數為e)、底數為10的log、底數為2的log、log(1+x) |
sign | 計算各元素的正負號:1(正數)、0(零)、-1(負數) |
ceil | 計算各元素的ceiling值,即大於等於該值的最小整數 |
floor | 計算各元素的floor值,即小於等於該值的最大整數 |
rint | 將各元素值四舍五入到最接近的整數,保留dtype |
modf | 將數組的小數和整數部分以兩個獨立數組的形式返回 |
isnan | 返回一個表示"哪些值是NaN(這不是一個數字)"的布爾型數組 |
isfinite、isinf | 分別返回一個表示"哪些元素是有窮的(非inf,非NaN)"或"哪些元素是無窮的"的布爾型數組 |
cos、cosh、sin、sinh、tan、tanh | 普通型和雙曲型三角函數 |
arccos、arccosh、arcsin、arcsinh、arctan、arctanh | 反三角函數 |
logical_not | 計算各元素notx的真值。相當於-arr |
二元ufunc
函數 | 說明 |
add | 將數組中對應的元素相加 |
subtract | 從第一個數組中減去第二個數組中的元素 |
multiply | 數組元素相乘 |
divide、floor_divide | 除法或向下圓整除法(丟棄余數) |
power | 對第一個數組中的元素A,根據第二個數組中的元素B,計算A的B次方 |
maximum、fmax | 元素級的最大值計算。fmax將忽略NaN |
minimum、fmin | 元素級的最小值計算。fmin將忽略NaN |
mod | 元素級的求模計算(除法的余數) |
copysign | 將第二個數組中的值的符號復制給第一個數組中的值 |
greater、greater_equal、 less、less_equal、equal、not_equal |
執行元素級的比較運算,最終產生布爾型數組。相當於中綴運算符>、>=、<、<=、==、!= |
logical_and、logical_or、logical_xor | 執行元素級的真值邏輯運算。相當於中綴運算符&、|、^ |
二.利用數組進行數據處理
Numpy數組使我們可以將許多種數據處理任務表述為簡潔的數組表達式(否則需要編寫循環)。用數組表達式代替循環的做法,通常被稱為矢量化。一般來說矢量化數組運算要比等價的純Python方式快上一兩個數量級(甚至更多),尤其是各種數值計算。
假設我們想在一組值(網格型)上計算函數sqrt(x^2+y^2),np.meshgrid函數接受兩個一維數組,並產生兩個二維矩陣(對應於兩個數組中所有的(x,y)對)
#coding:utf-8 import matplotlib.pyplot as plt import numpy as np points=np.arange(-5,5,0.01) #1000個間隔相等的點 xs,ys=np.meshgrid(points,points) print(xs) print(ys) [[-5. -4.99 -4.98 ... 4.97 4.98 4.99] [-5. -4.99 -4.98 ... 4.97 4.98 4.99] [-5. -4.99 -4.98 ... 4.97 4.98 4.99] ... [-5. -4.99 -4.98 ... 4.97 4.98 4.99] [-5. -4.99 -4.98 ... 4.97 4.98 4.99] [-5. -4.99 -4.98 ... 4.97 4.98 4.99]] ======================================== [[-5. -5. -5. ... -5. -5. -5. ] [-4.99 -4.99 -4.99 ... -4.99 -4.99 -4.99] [-4.98 -4.98 -4.98 ... -4.98 -4.98 -4.98] ... [ 4.97 4.97 4.97 ... 4.97 4.97 4.97] [ 4.98 4.98 4.98 ... 4.98 4.98 4.98] [ 4.99 4.99 4.99 ... 4.99 4.99 4.99]]
現在把這兩個數組當做兩個浮點數那樣編寫表達式即可
z = np.sqrt(xs ** 2 + ys ** 2) print(z) ======================================== [[7.07106781 7.06400028 7.05693985 ... 7.04988652 7.05693985 7.06400028] [7.06400028 7.05692568 7.04985815 ... 7.04279774 7.04985815 7.05692568] [7.05693985 7.04985815 7.04278354 ... 7.03571603 7.04278354 7.04985815] ... [7.04988652 7.04279774 7.03571603 ... 7.0286414 7.03571603 7.04279774] [7.05693985 7.04985815 7.04278354 ... 7.03571603 7.04278354 7.04985815] [7.06400028 7.05692568 7.04985815 ... 7.04279774 7.04985815 7.05692568]]
plt.imshow(z, cmap=plt.cm.gray) plt.colorbar() plt.title("Image plot of $\sqrt{x^2+y^2}$ for a grid of values") plt.show() #顯示圖形
1.將條件邏輯表述為數組運算
#numpy.where函數是三元表達式x if condition else y 的矢量化版本。假設我們有一個布爾數組和兩個值數組
xarr=np.array([6.1,6.2,6.3,6.4,6.5])
yarr=np.array([8.1,8.2,8.3,8.4,8.5])
cond=np.array([True,False,True,False,True])
#現在我們想根據cond中的值選取xarr和yarr的值:當cond為True,選取xarr的值,否則選取yarr的值。列表推導式的做法如下:
result=[(x if z else y) for x,y,z in zip(xarr,yarr,cond)]
print(result)
#這樣做有幾個問題,第一:它對大數組的處理速度不是很快(因為所有工作都是純python完成的),第二:無法用於多維數組。
#若用np.where,則可以將該功能寫的非常簡潔
result=np.where(cond,xarr,yarr)
print(result)
#np.where 的第二個和第三個參數不必是數組,它們都可以是標量值。在數據分析工作中,where通常用於根據另一個數組產生一個新的數組。
#假設有一個隨機數組組成的矩陣,我們希望將所有正值替換為2,所有負值替換為-2,若利用np.where,則會非常簡單
arr=np.random.randn(4,4)
print(arr)
new_arr=np.where(arr>0,2,-2)
# print(new_arr)
# print(np.where(arr>0,2,arr)) #只將正值設置為2
# print(np.where(arr<0,0,arr))#只將負值設置為0
#總結:
#np.where 有兩種用法:
#第一種用法np.where(conditions,x,y) if (condituons成立):數組變x else:數組變y,例子如上
#第二種用法np.where(conditions)相當於給出數組的下標
#一維數組
x = np.arange(16)
print(x[np.where(x>5)])
#輸出:(array([ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], dtype=int64),)
#二維數組
x = np.arange(16).reshape(4,4)
print(x)
print(np.where(x>5)) #這里的坐標是前面的是一維的坐標,后面是二維的坐標
2.數學和統計方法
可以通過數組上的一組數學函數對整個數組或某個軸向的數據進行統計計算。
arr=np.random.randn(5,4)
print(arr)
print(arr.mean())#axis 不設置值,對 m*n 個數求均值,返回一個實數
print(arr.sum())
print(arr.mean(axis=1)) #axis =1 :對各行求均值,返回 m 個元素的一維數組
print(arr.mean(axis=0)) #axis = 0:對各列求均值,返回 n個元素的一維數組
#其他如cumsum、cumprod之類的方法則不聚合,而是產生一個由中間結果組成的數組
arr1=np.array([[1,2,3],[4,5,6]])
print(arr1.cumsum(0)) #每列對應元素累計相加
print(arr1.cumsum(1)) #每行對應元素累計相加
print(arr1.cumprod(0))#每列對應元素累計相乘
print(arr1.cumprod(1)) #每行對應元素累計相乘
基本數組統計方法
方法 |
說明 |
sum |
對數組中全部或某軸向的元素求和。零長度的數組的sum為0 |
mean |
算術平均值。零長度的數組的mean為NaN |
std、var |
分別為標准差和方差,自由度可調(默認為n) |
max、min |
最大值和最小值 |
argmin、argmax |
分別為最小和最大元素的索引 |
cumsum |
所有元素的累計和 |
cumprod |
所有元素的累計積 |
#排序
#跟Python內置的列表類型一樣,Numpy數組也可以通過sort方法排序
arr=np.array([[1,4,2],[7,2,6]])
print(arr.sort(0)) #對0軸排序,每列從小到大排序
print(arr)
print(arr.sort(1)) #對1軸排序,每行從小到大排序
print(arr)
#唯一化以及其他的集合邏輯
#Numpy提供了一些針對一維ndarray的基本集合運算。最常用的可能要數np.unique了,它用於找出數組中的唯一值並返回已排序的結果
names=np.array(['Kobe','Calvin','Michale','James','Calvin','Kobe','Kobe','Calvin'])
print(np.unique(names))
numbers=np.array([2,3,8,5,8,8,24,1,6,3])
print(np.unique(numbers))
Numpy中的集合函數如下表:
方法 |
說明 |
unique(x) |
計算x中的唯一元素,並返回有序結果 |
intersect1d(x,y) |
計算x和y中的公共元素,並返回有序結果 |
union1d(x,y) |
計算x和y的並集,並返回有序結果 |
in1d(x,y) |
得到一個表示"x的元素是否包含於y"的布爾型數組 |
setdiff1d(x,y) |
集合額差,即元素在x中且不在y中 |
cumprod |
所有元素的累計積 |