NumPy(Numerical Python) 是 Python的一個很重要的第三方庫,支持大量的維度數(shù)組與矩陣運算,此外也針對數(shù)組運算提供大量的數(shù)學函數(shù)庫。很多其他科學計算的第三方庫都是以Numpy為基礎建立的,比如pandas的數(shù)據(jù)就是以numpy為基礎。
numpy 是一個科學計算庫 ,它的核心:多維數(shù)組-ndarray(數(shù)組)。ndarray 數(shù)據(jù)存儲方式和list不一樣,ndarray是用一塊整體的內(nèi)存來存儲數(shù)據(jù)的。
import numpy as np
通過list創(chuàng)建、然后使用np.array對其進行初始化而創(chuàng)建數(shù)組。
a = [1,2,3,4,5,6,7,8]arr = np.array(a)或者arr = np.array([[[1, 2]], [[2, 3]], [[3, 4]], [[4, 5]]])
通過reshape創(chuàng)建二維數(shù)組
x = np.arange(10).reshape((2, 5))print(x)print(x[1, 4])print(x.shape[0])# [[0 1 2 3 4]# [5 6 7 8 9]]# 9# 2
二維數(shù)組的索引方式有兩種,第一種是a[x][y]的方式,另一種是a[x,y],通常更推薦后者。
arr = np.array([[[1, 2]], [[2, 3]], [[3, 4]], [[4, 5]]])print(type(arr))print('arr:\n',arr)print('數(shù)組的維度:',arr.ndim)print('數(shù)組的形狀:',arr.shape)print('數(shù)組的元素個數(shù):',arr.size)print('數(shù)組的數(shù)組類型:',arr.dtype)print('數(shù)組的每個元素的大?。?,arr.itemsize)
輸出結果如下:
<class 'numpy.ndarray'>arr: [[[1 2]] [[2 3]] [[3 4]] [[4 5]]]數(shù)組的維度: 3數(shù)組的形狀: (4, 1, 2)數(shù)組的元素個數(shù): 8數(shù)組的數(shù)組類型: int32數(shù)組的每個元素的大小: 4
生成空數(shù)組,np.empty空數(shù)組創(chuàng)建
x = np.empty([3,2], dtype = int) print (x)
通過np.empty創(chuàng)建3*2的int的空數(shù)組,數(shù)組元素為隨機值,因為它們未初始化。
生成全0數(shù)組,,通過dtype可以指定數(shù)組中元素類型
z = np.zeros(10)print(z) # 默認是浮點數(shù) [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]z1 = np.zeros(10, dtype='int64')print(z1) # [0 0 0 0 0 0 0 0 0 0]
創(chuàng)建一個與給定數(shù)組具有相同形狀的數(shù)組,數(shù)組元素以 0 來填充。
numpy.zeros 可以直接指定要創(chuàng)建的數(shù)組的形狀,而 numpy.zeros_like 則是創(chuàng)建一個與給定數(shù)組具有相同形狀的數(shù)組。
# 創(chuàng)建一個 3x3 的二維數(shù)組arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 創(chuàng)建一個與 arr 形狀相同的,所有元素都為 0 的數(shù)組zeros_arr = np.zeros_like(arr)print(zeros_arr)
生成全1數(shù)組
one = np.ones(10, dtype='int64')print(one) # [1 1 1 1 1 1 1 1 1 1]
創(chuàng)建一個與給定數(shù)組具有相同形狀的數(shù)組,數(shù)組元素以 1 來填充。numpy.ones 可以直接指定要創(chuàng)建的數(shù)組的形狀,而 numpy.ones_like 則是創(chuàng)建一個與給定數(shù)組具有相同形狀的數(shù)組。
# 創(chuàng)建一個 3x3 的二維數(shù)組arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 創(chuàng)建一個與 arr 形狀相同的,所有元素都為 1 的數(shù)組ones_arr = np.ones_like(arr)print(ones_arr)
生成某個范圍內(nèi)的數(shù)組
aa = np.arange(10)# [0 1 2 3 4 5 6 7 8 9]bb = np.arange(0, 10, 3,dtype = float) # 指定起始點 終止點 以及 step# [0 3 6 9]
創(chuàng)建一個一維數(shù)組,數(shù)組是一個等差數(shù)列構成的
a = np.linspace(1,10,10)print(a)#[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]a = np.linspace(10, 20, 5, endpoint = False) # endpoint 設為 false,不包含終止值20print(a)#[10. 12. 14. 16. 18.]
創(chuàng)建一個于等比數(shù)列。
# 默認底數(shù)是 10a = np.logspace(1.0, 2.0, num = 10) print (a)#[ 10. 12.91549665 16.68100537 21.5443469 27.82559402 # 35.93813664 46.41588834 59.94842503 77.42636827 100. ]
生成單位矩陣,即生成對角為1的二維矩陣。
a = np.eye(10)print(a) # [[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]# [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]# [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]# [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]# [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]# [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]# [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]# [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]# [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]# [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]
array和list的切片區(qū)別
a = list(range(10))b = np.arange(10)a1 = a[0:4]b1 = b[0:4]print('a_list:{}'.format(a))print('b_array:{}'.format(b))print('a1_list:{}'.format(a1))print('b1_array:{}'.format(b1))print('修改a1[0]和b1[0]的值之后:')a1[0] = 11b1[0] = 11print('修改之后的a_list:{}'.format(a)) # list的值并沒有被修改 它相當于是一種淺拷貝print('修改之后的b_array:{}'.format(b)) # array的值被修改# 說明對array來說,切片操作其實是對原array的引用,實際上是一種淺拷貝
運行結果如下:
a_list:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]b_array:[0 1 2 3 4 5 6 7 8 9]a1_list:[0, 1, 2, 3]b1_array:[0 1 2 3]修改a1[0]和b1[0]的值之后:修改之后的a_list:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]修改之后的b_array:[11 1 2 3 4 5 6 7 8 9]
a = b,完全不復制,ab會相互影響;
a = b[:],切片操作,會創(chuàng)建新的對象a,但是兩者的變化是一致的;
a = b.copy(),復制,兩者互不影響,相當于深拷貝。
a = np.arange(15).reshape((3, 5))print(a)# [[ 0 1 2 3 4]# [ 5 6 7 8 9]# [10 11 12 13 14]]print(a[0:2, 0:2])# [[0 1]# [5 6]]print(a[0:2][0:2])# [[0 1 2 3 4]# [5 6 7 8 9]]# 只有前一種方法湊效print(a[1:, 2:4])# [[ 7 8]# [12 13]]
布爾索引
將布爾表達式作為索引
a = np.arange(10)b = a[a > 5]print(b)# [6 7 8 9]
其實它的實際操作是這樣的
c = np.array([1, 2, 3, 4])d = [True, True, False, True]print(c[d]) # [1, 2, 4]print(a > 5) # [False False False False False False True True True True]print(a[a > 5]) # [6 7 8 9]
取a中大于5的偶數(shù)
b = a[(a > 5) & (a % 2 == 0)] # 必須要加括號 并且不能用and 此處會重載運算符&print(b)# [6 8]
取a中大于5的數(shù)和所有偶數(shù)
c = a[(a > 5) | (a % 2 == 0)]print(c) # [0 2 4 6 7 8 9]
傳進去一個列表作為索引,可以取到相應位置上的值
也可以和切片操作、布爾索引結合
a = np.arange(20)print(a[[1, 3, 5, 7, 9]]) # [1 3 5 7 9]a = np.arange(20).reshape((4, 5))print(a)print(a[0, 2:4]) # [2, 3]print(a[0, a[0] > 1]) # [2, 3, 4]# [[ 0 1 2 3 4]# [ 5 6 7 8 9]# [10 11 12 13 14]# [15 16 17 18 19]]# 取a中的元素作為新的二維數(shù)組b = a[[1, 3], :] # 先切第1 3行c = b[:, [1, 3]] # 再切第1 3列print(c)# [[ 6 8]# [16 18]]print(a[[1, 3], :][:, [1, 3]]) # 效果同上print(a[[0, 2], :][:, [0, 1, 3, 4]])
nan(not a number)不是一個數(shù),類型是<class 'float'>。
兩個NaN是不相等的 np.nan == np.nan ==> False
np.nan != np.nan ==> True
# 判斷nan的方法是np.isnan(a)a = np.arange(5)a = a / aprint(a) # [nan 1. 1. 1. 1.]print(np.isnan(a)) # [True False False False False]# 去掉數(shù)組中nan的方法b = a[~np.isnan(a)] # [1. 1. 1. 1.]# 統(tǒng)計數(shù)組中nan的個數(shù)np.count_nonzero(a != a)
inf是無窮大,也是float型數(shù)據(jù)。用法同isnan
a = np.array([1, 1, 2, 3, 4])b = np.array([0, 1, 2, 1, 0])c = a / bprint(c) # [inf 1. 1. 3. inf]# 去除infprint(c[~(np.isinf(c))]) # [1. 1. 3.]
隨機產(chǎn)生一個數(shù)
t = np.random.rand(2,4) # 產(chǎn)生多個維度均勻分布的數(shù) 或者 數(shù)組 范圍0~1# [[0.90817816 0.75715337 0.64737834 0.79045973]# [0.80215137 0.04848201 0.66005689 0.32470002]]t = np.random.randn(4) # 產(chǎn)生多個維度成標準正態(tài)分布的數(shù)組 均值為0 標準差為1# [ 0.33196007 -1.59954454 -1.22863283 0.49101622]a = np.random.random()
np.random.randint(0, 10)a = np.random.randint(0, 10, 10) # 隨機生成10個0-9以內(nèi)的int 一維的# [9 0 2 3 2 0 8 9 2 6]a = np.random.randint(0, 10, (2, 5)) # 最后一參數(shù)是形狀 多維# [[4 8 7 0 3]# [7 6 8 1 8]]
a = np.random.uniform(2.0, 10.0, 10)print(a)# [3.10070825 2.54493484 8.07038208 6.74178579 2.9491971 9.9813392 3.58365099 8.4720269 4.73902394 6.50748841]a = np.random.uniform(2.0, 10.0, (2, 5))print(a)# [[6.86870706 8.48767828 3.35503304 2.35793278 6.05281056]# [9.67359048 3.16650548 7.81726608 2.72933486 2.22826293]]
因為計算機每次生成的都是偽隨機數(shù),在指定隨機數(shù)種子之后,生成的隨機數(shù)就不會改變。
np.random.seed(4)t = np.random.randint(0, 10, (2, 5))print(t)# [[7 5 1 8 7]# [8 2 9 7 7]]
a = np.random.choice([1, 2, 3, 4, 5], 10) # 最后一個參數(shù)是生成數(shù)組的形狀print(a) # [2 2 2 2 1 1 3 5 3 3]
np.where函數(shù)的使用,可以理解為:
(1)三個參數(shù)np.where(condition,x,y) : 滿足條件(condition)輸出x, 不滿足則輸出y ;
(2)一個參數(shù)np.where(arr) : 輸出arr中“真”值的坐標,簡單理解為不為0的坐標。
x=np.arange(1,10).reshape(3,3)np.where(x>3,x,11111)# [[11111 11111 11111]# [ 4 5 6]# [ 7 8 9]]
print(np.maximum(a, b))print(np.minimum(a, b))a = np.array([1, 2, 3, 4, 5])# 若a是二維數(shù)組,則可以指定axis用以在不同軸上取數(shù)據(jù)t1 = np.arange(0, 20).reshape((4, 5))print(t1.sum(axis=0)) # 枚舉行# [30 34 38 42 46]print(t1.sum(axis=1)) # 枚舉列# [10 35 60 85]print(a.max())print(a.min())print(a.mean())print(a.sum())print(a.argmax())print(a.argmin())print(a.std())print(a.var())
a = np.arange(-5, 5, 0.6)print(a)print(np.floor(a)) # 向上取整print(np.ceil(a)) # 向下取整print(np.rint(a)) # 四舍五入print(np.round(a)) # 四舍五入print(np.trunc(a)) # 截斷小數(shù)部分
垂直拼接需要保證兩個數(shù)組在列維度上大小相同
水平拼接需要保證兩個數(shù)組在行維度上大小相同
# 垂直拼接t1 = np.arange(0, 10).reshape((2, 5))t2 = np.arange(11, 21).reshape((2, 5))tv = np.vstack((t1, t2))print(tv)# [[ 0 1 2 3 4]# [ 5 6 7 8 9]# [11 12 13 14 15]# [16 17 18 19 20]]
# 水平拼接
t1 = np.arange(0, 10).reshape((2, 5))t2 = np.arange(11, 21).reshape((2, 5))th = np.hstack((t1, t2))print(th)# [[ 0 1 2 3 4 11 12 13 14 15]# [ 5 6 7 8 9 16 17 18 19 20]]
t1 = np.arange(0, 20).reshape((4, 5))print(t1)# [[ 0 1 2 3 4]# [ 5 6 7 8 9]# [10 11 12 13 14]# [15 16 17 18 19]]t1[[1, 2], :] = t1[[2, 1], :] # 行交換之后print(t1)# [[ 0 1 2 3 4]# [10 11 12 13 14]# [ 5 6 7 8 9]# [15 16 17 18 19]]t1[:, [0, 1]] = t1[:, [1, 0]] # 列交換之后print(t1)# [[ 1 0 2 3 4]# [11 10 12 13 14]# [ 6 5 7 8 9]# [16 15 17 18 19]]
NumPy 中包含了一個矩陣庫 numpy.matlib,該模塊中的函數(shù)返回的是一個矩陣,而不是 ndarray 對象。
NumPy 中除了可以使用 numpy.transpose 函數(shù)來對換數(shù)組的維度,還可以使用 T 屬性。
# 水平拼接
a = np.arange(12).reshape(3,4) print ('原數(shù)組:')print (a)# 原數(shù)組:# [[ 0 1 2 3]# [ 4 5 6 7]# [ 8 9 10 11]]print ('\n') print ('轉置數(shù)組:')print (a.T)#轉置數(shù)組:# [[ 0 4 8]# [ 1 5 9]# [ 2 6 10]# [ 3 7 11]]
加法、減法、乘法、除法、整除、乘方、求余、求倒數(shù)、求絕對值、求三角函數(shù)和反三角函數(shù)、以 e 為底的函數(shù)值、n 的 x 次方、求對數(shù)函數(shù)等。這個很好理解,就是對矩陣中每個元素進行計算。
import numpy as npx = np.arange(1,16).reshape(3,5)print(x)# 加法(減法)x1 = x + 1print(x1)# 除法(乘法)x2 = 2 * xprint(x2)x3 = 2 / xprint(x3)# 向下取整x4 = x // 3print(x4)# 取余x5 = x % 3print(x5)#絕對值x6 = np.abs(x)print(x6)#正弦sinx = np.sin(x)print(sinx) #余弦cosx = np.cos(x)print(cosx) #正切tanx = np.tan(x)print(tanx) # 反正弦 arcsinx = np.arcsin(x)print(arcsinx)# 反余弦arccosx = np.arccos(x)print(arccosx)# 反正切arctanx = np.arctan(x)print(arctanx)#次方運算xxx = x **3print(xxx)xx = 2 ** xprint(xx)# 指數(shù)函數(shù)e**xexpx = np.exp(x)#開平方:sqrtsqrtx = np.sqrt(x)print(sqrtx)#power(a,b):求a的b次方powerx = np.power(2,x)#log函數(shù):不指定值時默認就是loge函數(shù),以e為底的對數(shù)lnx = np.log(x)print(lnx)#long2:以2為底的對數(shù)ln2x = np.log2(x)print(ln2x)#long10:以10為底的對數(shù)ln10x = np.log10(x)print(ln10x)
矩陣的運算:兩個矩陣加法、減法、乘法。
A = np.arange(4).reshape(2,2)B = np.full((2,2),10)# 矩陣間的加減法AB = A + Bprint(AB)A_B = A - Bprint(A_B)# 矩陣的乘法AB = A.dot(B)print(AB)# 兩矩陣間如僅用乘號(*)相連接,計算結果為兩矩陣對應元素相乘的結果AB = A * Bprint(AB)
# 矩陣的轉置AT = A.Tprint(AT)
加法(數(shù)學上無意義),相當于將矩陣的每一行加上向量對應的值。
[[37 加法(數(shù)學上無意義)40] [85 92]]
乘法(與矩陣間計算相似),注:向量與矩陣相乘時,若不滿足數(shù)學計算規(guī)則,numpy會自動將矩陣進行轉置。
np.title(v, (2,2))np.title(v, (2,1))
np.linalg.inv()
np.linalg.pinv()
函數(shù) | 描述 |
dot | 兩個數(shù)組的點積,即元素對應相乘。 |
vdot | 兩個向量的點積 |
inner | 兩個數(shù)組的內(nèi)積 |
matmul | 兩個數(shù)組的矩陣積 |
determinant | 數(shù)組的行列式 |
solve | 求解線性矩陣方程 |
inv | 計算矩陣的乘法逆矩陣 |
a = np.array([[1,2],[3,4]])b = np.array([[11,12],[13,14]])print(np.dot(a,b))
輸出結果為:[[37 40] [85 92]]
計算式為:[[1*11+2*13, 1*12+2*14],[3*11+4*13, 3*12+4*14]]
numpy.vdot() 函數(shù)是兩個向量的點積。 如果第一個參數(shù)是復數(shù),那么它的共軛復數(shù)會用于計算。 如果參數(shù)是多維數(shù)組,它會被展開。
import numpy as np a = np.array([[1,2],[3,4]]) b = np.array([[11,12],[13,14]]) # vdot 將數(shù)組展開計算內(nèi)積print (np.vdot(a,b))#130
計算式為:1*11 + 2*12 + 3*13 + 4*14 = 130
numpy.inner() 函數(shù)返回一維數(shù)組的向量內(nèi)積。對于更高的維度,它返回最后一個軸上的和的乘積。
import numpy as np print (np.inner(np.array([1,2,3]),np.array([0,1,0])))# 等價于 1*0+2*1+3*0#2
多維數(shù)組:
import numpy as np a = np.array([[1,2], [3,4]]) b = np.array([[11, 12], [13, 14]]) print ('內(nèi)積:')print (np.inner(a,b))# 內(nèi)積:# [[35 41]# [81 95]]
內(nèi)積計算式為:
1*11+2*12, 1*13+2*14
3*11+4*12, 3*13+4*14
numpy.linalg.det() 函數(shù)計算輸入矩陣的行列式。
行列式在線性代數(shù)中是非常有用的值。 它從方陣的對角元素計算。 對于 2×2 矩陣,它是左上和右下元素的乘積與其他兩個的乘積的差。
換句話說,對于矩陣[[a,b],[c,d]],行列式計算為 ad-bc。 較大的方陣被認為是 2×2 矩陣的組合。
import numpy as npa = np.array([[1,2], [3,4]]) print (np.linalg.det(a))#-2.0
numpy.linalg.solve() 函數(shù)給出了矩陣形式的線性方程的解。
求解方程組 x0 + 2 * x1 = 1 和 3 * x0 + 5 * x1 = 2 :
a = np.array([[1, 2], [3, 5]])b = np.array([1, 2])x = np.linalg.solve(a, b)# [-1., 1.]# x0=-1 x1=1
numpy.linalg.inv() 函數(shù)計算矩陣的乘法逆矩陣。
逆矩陣(inverse matrix):設A是數(shù)域上的一個n階矩陣,若在相同數(shù)域上存在另一個n階矩陣B,使得: AB=BA=E ,則我們稱B是A的逆矩陣,而A則被稱為可逆矩陣。注:E為單位矩陣。
保存的文件是以.npy為后綴的二進制文件,參數(shù)1: 保存的文件路徑名稱,可省略文件名后綴。
np.save('./arr1',arr1)
arr = np.load('./arr1.npy')
默認保存的是以.npz結尾的二進制文件
np.savez('./arr2', arr1, arr2)
多個數(shù)組時,是以鍵值對存儲的。
參數(shù):fmt---保存的數(shù)組數(shù)據(jù)類型,delimiter---分隔符
np.savetxt('./arr1.txt', fmt='%d',delimiter=' ')np.savetxt('./arr1.csv', fmt='%d',delimiter=',')
data = np.loadtxt('./arr1.txt', dtype=float,delimiter=' ')
genfromtxt讀取文件和loadtxt類似,所不同的是,參數(shù)filling_values 指定缺失時填充的數(shù)據(jù)。
data = np.genfromtxt('./arr1.txt',dtype=int,delimiter=' ', filling_values=9999)
arr.sort()
res = arr.argsort()
#axis=1, 按列res = np.repeat(arr1,2,axis=1)#axis=0, 按行res = np.repeat(arr1,2,axis=0)
以下函數(shù)用于對 dtype 為 numpy.string_ 或 numpy.unicode_ 的數(shù)組執(zhí)行向量化字符串操作。 它們基于 Python 內(nèi)置庫中的標準字符串函數(shù)。這些函數(shù)在字符數(shù)組類(numpy.char)中定義。
函數(shù) | 描述 |
add() | 對兩個數(shù)組的逐個字符串元素進行連接 |
multiply() | 返回按元素多重連接后的字符串 |
center() | 居中字符串 |
capitalize() | 將字符串第一個字母轉換為大寫 |
title() | 將字符串的每個單詞的第一個字母轉換為大寫 |
lower() | 數(shù)組元素轉換為小寫 |
upper() | 數(shù)組元素轉換為大寫 |
split() | 指定分隔符對字符串進行分割,并返回數(shù)組列表 |
splitlines() | 返回元素中的行列表,以換行符分割 |
strip() | 移除元素開頭或者結尾處的特定字符 |
join() | 通過指定分隔符來連接數(shù)組中的元素 |
replace() | 使用新字符串替換字符串中的所有子字符串 |
decode() | 數(shù)組元素依次調(diào)用str.decode |
encode() | 數(shù)組元素依次調(diào)用str.encode |
#妙筆生花創(chuàng)作挑戰(zhàn)#