您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關Python中常用的數學建模Numpy,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
三劍客之Numpy
numpy是一個開源的python科學計算庫,包含了很多實用的數學函數,涵蓋線性代數、傅里葉變換和隨機數生成等功能。最初的numpy其實是scipy的一部分,后來才從scipy中分離出來。
numpy不是python的標準庫,需要單獨安裝。假定你的運行環境已經安裝了python包管理工具pip,numpy的安裝就非常簡單:
pip install numpy
一、數組對象
ndarray是多維數組對象,也是numpy最核心的對象。在numpy中,數組的維度(dimensions)叫做軸(axes),軸的個數叫做秩(rank)。通常,一個numpy數組的所有元素都是同一種類型的數據,而這些數據的存儲和數組的形式無關。
下面的例子,創建了一個三維的數組(在導入numpy時,一般都簡寫成np)。
import numpy as np a = np.array([[1,2,3],[4,5,6],[7,8,9]])
1、數據類型
numpy支持的數據類型主要有布爾型(bool)、整型(integrate)、浮點型(float)和復數型(complex),每一種數據類型根據占用內存的字節數又分為多個不同的子類型。常見的數據類型見下表。
2、創建數組
通常,我們用np.array()創建數組。如果僅僅是創建一維數組,也可以使用np.arange()或者np.linspace()的方法。np.zeros()、np.ones()、np.eye()則可以構造特殊的數據。np.random.randint()和np.random.random()則可以構造隨機數數組。
>>> np.array([[1,2,3],[4,5,6]]) # 默認元素類型為int32 array([[1, 2, 3], [4, 5, 6]]) >>> np.array([[1,2,3],[4,5,6]], dtype=np.int8) # 指定元素類型為int8 array([[1, 2, 3], [4, 5, 6]], dtype=int8) >>> np.arange(5) # 默認元素類型為int32 array([0, 1, 2, 3, 4]) >>> np.arange(3,8, dtype=np.int8) # 指定元素類型為int8 array([3, 4, 5, 6, 7], dtype=int8) >>> np.arange(12).reshape(3,4) # 改變shape array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> np.linspace(1,2,5) # 從1到2生成5個浮點數 array([ 1. , 1.25, 1.5 , 1.75, 2. ]) >>> np.zeros((2,3)) # 全0數組 array([[ 0., 0., 0.], [ 0., 0., 0.]]) >>> np.ones((2,3)) # 全1數組 array([[ 1., 1., 1.], [ 1., 1., 1.]]) >>> np.eye(3) # 主對角線元素為1其他元素為0 array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]) >>> np.random.random((2,3)) # 生成[0,1)之間的隨機浮點數 array([[ 0.84731148, 0.8222318 , 0.85799278], [ 0.59371558, 0.92330741, 0.04518351]]) >>> np.random.randint(0,10,(3,2)) # 生成[0,10)之間的隨機整數 array([[2, 4], [8, 3], [8, 5]])
3、構造復雜數組
很多時候,我們需要從簡單的數據結構,構造出復雜的數組。例如,用一維的數據生成二維格點。
(1)重復數組:tile
>>> a = np.arange(5) >>> a array([0, 1, 2, 3, 4]) >>> np.tile(a, 2) array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4]) >>> np.tile(a, (3,2)) array([[0, 1, 2, 3, 4, 0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]])
(2)重復元素:repeat
>>> a = np.arange(5) >>> a array([0, 1, 2, 3, 4]) >>> a.repeat(2) array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4])
(3)一維數組網格化:meshgrid
>>> a = np.arange(5) >>> b = np.arange(5,10) >>> np.meshgrid(a,b) [array([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]), array([[5, 5, 5, 5, 5], [6, 6, 6, 6, 6], [7, 7, 7, 7, 7], [8, 8, 8, 8, 8], [9, 9, 9, 9, 9]])] >>>
(4)指定范圍和分割方式的網格化:mgrid
>>> np.mgrid[0:1:2j, 1:2:3j] array([[[ 0. , 0. , 0. ], [ 1. , 1. , 1. ]], [[ 1. , 1.5, 2. ], [ 1. , 1.5, 2. ]]]) >>> np.mgrid[0:1:0.3, 1:2:0.4] array([[[ 0. , 0. , 0. ], [ 0.3, 0.3, 0.3], [ 0.6, 0.6, 0.6], [ 0.9, 0.9, 0.9]], [[ 1. , 1.4, 1.8], [ 1. , 1.4, 1.8], [ 1. , 1.4, 1.8], [ 1. , 1.4, 1.8]]])
上面的例子中用到了虛數。構造虛數的方法如下:
>>> complex(2,5) (2+5j)
4、數組的屬性
numpy的數組對象除了一些常規的屬性外,也有幾個類似轉置、扁平迭代器等看起來更像是方法的屬性。扁平迭代器也許是遍歷多維數組的一個簡明方法,下面的代碼給出了一個例子。
>>> a = np.array([[1,2,3],[4,5,6]]) >>> a.dtype # 數組元素的數據類型 dtype('int32') >>> a.dtype.itemsize # 數組元素占據的內存字節數 4 >>> a.itemsize # 數組元素占據的內存字節數 4 >>> a.shape # 數組的維度 (2, 3) >>> a.size # 數組元素個數 6 >>> a.T # 數組行變列,類似于transpose() array([[1, 4], [2, 5], [3, 6]]) >>> a.flat # 返回一個扁平迭代器,用于遍歷多維數組 <numpy.flatiter object at 0x037188F0> >>> for item in a.flat: print item
5、改變數組維度
numpy數組的存儲順序和數組的維度是不相干的,因此改變數組的維度是非常便捷的操作,除resize()外,這一類操作不會改變所操作的數組本身的存儲順序。
>>> a = np.array([[1,2,3],[4,5,6]]) >>> a.shape # 查看數組維度 (2, 3) >>> a.reshape(3,2) # 返回3行2列的數組 array([[1, 2], [3, 4], [5, 6]]) >>> a.ravel() # 返回一維數組 array([1, 2, 3, 4, 5, 6]) >>> a.transpose() # 行變列(類似于矩陣轉置) array([[1, 4], [2, 5], [3, 6]]) >>> a.resize((3,2)) # 類似于reshape,但會改變所操作的數組 >>> a array([[1, 2], [3, 4], [5, 6]])
6、索引和切片
對于一維數組的索引和切片,numpy和python的list一樣,甚至更靈活。
a = np.arange(9) >>> a[-1] # 最后一個元素 8 >>> a[2:5] # 返回第2到第5個元素 array([2, 3, 4]) >>> a[:7:3] # 返回第0到第7個元素,步長為3 array([0, 3, 6]) >>> a[::-1] # 返回逆序的數組 array([8, 7, 6, 5, 4, 3, 2, 1, 0])
假設有一棟2層樓,每層樓內的房間都是3排4列,那我們可以用一個三維數組來保存每個房間的居住人數(當然,也可以是房間面積等其他數值信息)。
>>> a = np.arange(24).reshape(2,3,4) # 2層3排4列 >>> a 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]]]) >>> a[1][2][3] # 雖然可以這樣 23 >>> a[1,2,3] # 但這才是規范的用法 23 >>> a[:,0,0] # 所有樓層的第1排第1列 array([ 0, 12]) >>> a[0,:,:] # 1樓的所有房間,等價與a[0]或a[0,...] array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> a[:,:,1:3] # 所有樓層所有排的第2到4列 array([[[ 1, 2], [ 5, 6], [ 9, 10]], [[13, 14], [17, 18], [21, 22]]]) >>> a[1,:,-1] # 2層每一排的最后一個房間 array([15, 19, 23])
7、數組合并
數組合并除了下面介紹的水平合并、垂直合并、深度合并外,還有行合并、列合并,以及concatenate()等方式。假如你比我還懶,那就只了解前三種方法吧,足夠用了。
>>> a = np.arange(9).reshape(3,3) >>> b = np.arange(9,18).reshape(3,3) >>> a array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) >>> b array([[ 9, 10, 11], [12, 13, 14], [15, 16, 17]]) >>> np.hstack((a,b)) # 水平合并 array([[ 0, 1, 2, 9, 10, 11], [ 3, 4, 5, 12, 13, 14], [ 6, 7, 8, 15, 16, 17]]) >>> np.vstack((a,b)) # 垂直合并 array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14], [15, 16, 17]]) >>> np.dstack((a,b)) # 深度合并 array([[[ 0, 9], [ 1, 10], [ 2, 11]], [[ 3, 12], [ 4, 13], [ 5, 14]], [[ 6, 15], [ 7, 16], [ 8, 17]]])
8、數組拆分
拆分是合并的逆過程,概念是一樣的,但稍微有一點不同:
>>> a = np.arange(9).reshape(3,3) >>> np.hsplit(a, 3) # 水平拆分,返回list [array([[0], [3], [6]]), array([[1], [4], [7]]), array([[2], [5], [8]])] >>> np.vsplit(a, 3) # 垂直拆分,返回list [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])] >>> a = np.arange(27).reshape(3,3,3) >>> np.dsplit(a, 3) # 深度拆分,返回list [array([[[ 0], [ 3], [ 6]], [[ 9], [12], [15]], [[18], [21], [24]]]), array([[[ 1], [ 4], [ 7]], [[10], [13], [16]], [[19], [22], [25]]]), array([[[ 2], [ 5], [ 8]], [[11], [14], [17]], [[20], [23], [26]]])]
9、數組運算
數組和常數的四則運算,是數組的每一個元素分別和常數運算;數組和數組的四則運算則是兩個數組對應元素的運算(兩個數組有相同的shape,否則拋出異常)。
>>> a = np.arange(4, dtype=np.float32).reshape(2,2) >>> b = np.arange(4, 8, dtype=np.float32).reshape(2,2) >>> a+2 # 數組和常數可以進行四則運算 array([[ 2., 3.], [ 4., 5.]], dtype=float32) >>> a/b # 數組和數組可以進行四則運算 array([[ 0. , 0.2 ], [ 0.33333334, 0.42857143]], dtype=float32) >>> a == b # 最神奇的是,數組可以判斷對應元素是否相等 array([[False, False], [False, False]], dtype=bool) >>> (a == b).all() # 判斷數組是否相等 False
特別提示:如果想對數組內符合特定條件的元素做特殊處理,下面的代碼也許有用。
>>> a = np.arange(6).reshape((2,3)) >>> a array([[0, 1, 2], [3, 4, 5]]) >>> (a>2)&(a<=4) array([[False, False, False], [ True, True, False]], dtype=bool) >>> a[(a>2)&(a<=4)] array([3, 4]) >>> a[(a>2)&((a<=4))] += 10 >>> a array([[ 0, 1, 2], [13, 14, 5]])
10、數組方法和常用函數
數組對象本身提供了計算算數平均值、求最大最小值等內置方法,numpy也提供了很多實用的函數。為了縮減篇幅,下面的代碼僅以一維數組為例,展示了這些方法和函數用法。事實上,大多數情況下這些方法和函數對于多維數組同樣有效,只有少數例外,比如compress函數。
>>> a = np.array([3,2,4]) >>> a.sum() # 所有元素的和 9 >>> a.prod() # 所有元素的乘積 24 >>> a.mean() # 所有元素的算數平均值 3.0 >>> a.max() # 所有元素的最大值 4 >>> a.min() # 所有元素的最小值 2 >>> a.clip(3,4) # 小于3的元素替換為3,大于4的元素替換為4 array([3, 3, 4]) >>> a.compress(a>2) # 返回大于2的元素組成的數組 array([3, 4]) >>> a.tolist() # 返回python的list [3, 2, 4] >>> a.var() # 計算方差(元素與均值之差的平方的均值) 0.66666666666666663 >>> a.std() # 計算標準差(方差的算術平方根) 0.81649658092772603 >>> a.ptp() # 返回數組的最大值和最小值之差 2 >>> a.argmin() # 返回最小值在扁平數組中的索引 1 >>> a.argmax() # 返回最大值在扁平數組中的索引 2 >>> np.where(a == 2) # 返回所有值為2的元素的索引 (array([1]),) >>> np.diff(a) # 返回相鄰元素的差 array([-1, 2]) >>> np.log(a) # 返回對數數組 array([ 1.09861229, 0.69314718, 1.38629436]) >>> np.exp(a) # 返回指數數組 array([ 20.08553692, 7.3890561 , 54.59815003]) >>> np.sqrt(a) # 返回開方數組 array([ 1.73205081, 1.41421356, 2. ]) >>> np.msort(a) # 數組排序 array([2, 3, 4]) >>> a = np.array([1,4,7]) >>> b = np.array([8,5,2]) >>> np.maximum(a, b) # 返回多個數組中對應位置元素的最大值數組 array([8, 5, 7]) >>> np.minimum(a, b) # 返回多個數組中對應位置元素的最小值數組 array([1, 4, 2]) >>> np.true_divide(a, b) # 對整數實現真正的數學除法運算 array([ 0.125, 0.8 , 3.5 ])
二、矩陣對象
matrix是矩陣對象,繼承自ndarray類型,因此含有ndarray的所有數據屬性和方法。不過,當你把矩陣對象當數組操作時,需要注意以下幾點:
matrix對象總是二維的,即使是展平(ravel函數)操作或是成員選擇,返回值也是二維的
matrix對象和ndarray對象混合的運算總是返回matrix對象
1、創建矩陣
matrix對象可以使用一個Matlab風格的字符串來創建(以空格分隔列,以分號分隔行的字符串),也可以用數組來創建。
>>> np.mat('1 4 7; 2 5 8; 3 6 9') matrix([[1, 4, 7], [2, 5, 8], [3, 6, 9]]) >>> np.mat(np.arange(1,10).reshape(3,3)) matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
2、矩陣的特有屬性
矩陣有幾個特有的屬性使得計算更加容易,這些屬性有:
>>> m = np.mat(np.arange(1,10).reshape(3,3)) >>> m matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> m.T # 返回自身的轉置 matrix([[1, 4, 7], [2, 5, 8], [3, 6, 9]]) >>> m.H # 返回自身的共軛轉置 matrix([[1, 4, 7], [2, 5, 8], [3, 6, 9]]) >>> m.I # 返回自身的逆矩陣 matrix([[ -4.50359963e+15, 9.00719925e+15, -4.50359963e+15], [ 9.00719925e+15, -1.80143985e+16, 9.00719925e+15], [ -4.50359963e+15, 9.00719925e+15, -4.50359963e+15]]) >>> m.A # 返回自身數據的二維數組的一個視圖 array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
3、矩陣乘法
對ndarray對象而言,星號是按元素相乘,dot()函數則當作矩陣相乘。對于matrix對象來說,星號和dot()函數都是矩陣相乘。特別的,對于一維數組,dot()函數實現的是向量點乘(結果是標量),但星號實現的卻不是差乘。
>>> a = np.array([1,2,3]) >>> b = np.array([4,5,6]) >>> a*b # 一維數組,元素相乘 array([ 4, 10, 18]) >>> np.dot(a,b) # 一維數組,元素相乘再求和 32 >>> a = np.array([[1,2],[3,4]]) >>> b = np.array([[5,6],[7,8]]) >>> a*b # 多維數組,元素相乘 array([[ 5, 12], [21, 32]]) >>> np.dot(a,b) # 多維數組,實現的是矩陣相乘 array([[19, 22], [43, 50]]) >>> m = np.mat(a) >>> n = np.mat(b) >>> np.dot(m,n) # 矩陣相乘 matrix([[19, 22], [43, 50]]) >>> m*n # 矩陣相乘 matrix([[19, 22], [43, 50]])
三、線性代數模塊
numpy.linalg 是numpy的線性代數模塊,可以用來解決逆矩陣、特征值、線性方程組以及行列式等問題。
1、計算逆矩陣
盡管matrix對象本身有逆矩陣的屬性,但用numpy.linalg模塊求解矩陣的逆,也是非常簡單的。
m = np.mat('0 1 2; 1 0 3; 4 -3 8') mi = np.linalg.inv(m) # mi即為m的逆矩陣。何以證明? m * mi # 矩陣與其逆矩陣相乘,結果為單位矩陣 matrix([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]])
2、計算行列式
如何計算行列式,我早已經不記得了,但手工計算行列式的痛苦,我依然記憶猶新。現在好了,你在手機上都可以用numpy輕松搞定(前提是你的手機上安裝了python + numpy)。
m = np.mat('0 1 2; 1 0 3; 4 -3 8') np.linalg.det(m) # 什么?這就成了? 2.0
3、計算特征值和特征向量
m = np.mat('0 1 2; 1 0 3; 4 -3 8') >>> np.linalg.eigvals(m) # 計算特征值 array([ 7.96850246, -0.48548592, 0.51698346]) >>> np.linalg.eig(m) # 返回特征值及其對應特征向量的元組 (array([ 7.96850246, -0.48548592, 0.51698346]), matrix([[ 0.26955165, 0.90772191, -0.74373492], [ 0.36874217, 0.24316331, -0.65468206], [ 0.88959042, -0.34192476, 0.13509171]]))
4、求解線性方程組
有線性方程組如下:
x - 2y + z = 0 2y -8z = 8 -4x + 5y + 9z = -9
求解過程如下:
>>> A = np.mat('1 -2 1; 0 2 -8; -4 5 9') >>> b = np.array([0, 8, -9]) >>> np.linalg.solve(A, b) array([ 29., 16., 3.]) # x = 29, y = 16, z = 3
以上就是Python中常用的數學建模Numpy,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。