這篇文章將為大家詳細講解有關Python中numpy有什么用,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
具體如下:
1 數據結構
numpy使用一種稱為ndarray的類似Matlab的矩陣式數據結構管理數據,比python的列表和標準庫的array類更為強大,處理數據更為方便。
1.1 數組的生成
在numpy中,生成數組需要指定數據類型,默認是int32,即整數,可以通過dtype參數來指定,一般用到的有int32、bool、float32、uint32、complex,分別代表整數、布爾值、浮點型、無符號整數和復數
一般而言,生成數組的方法有這么幾種:
以list列表為參數生成(用tolist方法即可轉換回list):
In[3]: a = array([1, 2, 3]) In[4]: a Out[4]: array([1, 2, 3]) In[5]: a.tolist() Out[5]: [1, 2, 3]
指定起點、終點和步長生成等差序列或等比數列:
In[7]: a = arange(1, 10, 2) In[8]: a Out[8]: array([1, 3, 5, 7, 9])
In[13]: a = linspace(0, 10, 5) In[14]: a Out[14]: array([ 0. , 2.5, 5. , 7.5, 10. ])
In[148]: a = logspace(0, 3, 10) # 0表示起點為10^0,3表示起點為10^3,基數通過base參數指定 In[149]: a Out[148]: array([ 1. , 2.15443469, 4.64158883, 10. , 21.5443469 , 46.41588834, 100. , 215.443469 , 464.15888336, 1000. ])
從迭代器中生成:
In[17]: iter = (i for i in range(5)) In[18]: a = fromiter(iter, dtype=int32) In[19]: a Out[19]: array([0, 1, 2, 3, 4])
從函數中生成:
In[156]: def f(i, j): ... return abs(i-j) ... In[157]: fromfunction(f, (4, 4)) Out[156]: array([[ 0., 1., 2., 3.], [ 1., 0., 1., 2.], [ 2., 1., 0., 1.], [ 3., 2., 1., 0.]])
還可以用zeros、ones、empty等函數快速創建數組。
矩陣視為二維數組:
In[24]: b = array([arange(5), arange(1, 6), arange(2, 7)]) In[25]: b Out[25]: array([[0, 1, 2, 3, 4], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6]])
根據相同的方法可以拓展到更高維。
另外,我們還可以生成自定義數據格式的數組(稱為結構數組),用來記錄電子表格或數據庫中一行數據的信息:
In[61]: t = dtype([('name', str, 40), ('number', int32), ('score', float32)]) In[62]: t Out[62]: dtype([('name', '<U40'), ('number', '<i4'), ('score', '<f4')]) In[63]: students = array([('Tom', 10, 80), ('Jenny', 11, 90.5), ('Mike', 9, 98.5)], dtype=t) In[64]: students Out[64]: array([('Tom', 10, 80.0), ('Jenny', 11, 90.5), ('Mike', 9, 98.5)], dtype=[('name', '<U40'), ('number', '<i4'), ('score', '<f4')]) In[65]: students[1] Out[65]: ('Jenny', 11, 90.5)
后面我們會看到pandas提供了一種更精致的方法處理記錄。
1.2 數組的索引
簡單的下標索引:
In[30]: a[2] Out[30]: 2 In[31]: b[2, 1] Out[31]: 3
與python一樣,索引的起點為0。負數的索引當然也是可以的:
In[32]: a[-1] Out[32]: 4 In[33]: b[-1, -2] Out[33]: 5
以整數數組為下標索引,一次性索引多個值:
In[162]: arange(11, 20)[array([2, 4, 8])] Out[161]: array([13, 15, 19])
還可以通過布爾值來索引:
In[40]: idx = array([True, False, False, True, True]) In[41]: a[idx] Out[41]: array([0, 3, 4])
這可以應用在高級索引中,比如條件索引:
b[b>3] Out[42]: array([4, 4, 5, 4, 5, 6])
得到b中所有大于3的元素,以array形式返回,我們能這么寫的原因是b>3會返回一個布爾數組,形式與b一致,各位置的值是b中各元素與3比較之后的結果:
In[43]: b>3 Out[43]: array([[False, False, False, False, True], [False, False, False, True, True], [False, False, True, True, True]], dtype=bool)
1.3 數組的切片
ndarray數組支持各種形式的切片,既可以以下標為線索,還可以以值為線索,為了區分二者,重新生成一個數組:
a = arange(11, 20) In[54]: a Out[54]: array([11, 12, 13, 14, 15, 16, 17, 18, 19])
根據下標切片:
In[55]: a[1:4] Out[55]: array([12, 13, 14]) In[56]: a[1:8:2] Out[56]: array([12, 14, 16, 18]) In[57]: a[1::2] Out[57]: array([12, 14, 16, 18]) In[58]: a[:8:] Out[58]: array([11, 12, 13, 14, 15, 16, 17, 18])
方括號中三個參數為別是起點、終點和步長,默認值分別是0、-1、1,注意終點是不被包含的??梢院唵蔚亓畈介L為-1來翻轉數組:
In[60]: a[::-1] Out[60]: array([19, 18, 17, 16, 15, 14, 13, 12, 11])
ndarray也支持多維數組的切片,先生成一個三維數組,可以通過修改一維數組的shape屬性或調用其reshape方法來生成:
In[68]: a = arange(0, 24).reshape(2, 3, 4) In[69]: a Out[69]: 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]]])
多維數組的索引其實跟一維區別不大,可以用:代表選取所有:
In[70]: a[:, 0, 0] Out[70]: array([ 0, 12]) In[71]: a[0, :, 0] Out[71]: array([0, 4, 8]) In[72]: a[0, 0, :] Out[72]: array([0, 1, 2, 3]) In[73]: a[0, 0:2, 0:3] Out[73]: array([[0, 1, 2], [4, 5, 6]])
多個冒號還可以用...
來代替:
In[74]: a[...,3] Out[74]: array([[ 3, 7, 11], [15, 19, 23]])
最后,可以使用slice對象來表示切片,它與用1:10:2
形式產生切片類似:
In[169]: idx = slice(None, None, 2) In[171]: a[idx,idx,idx] Out[170]: array([[[ 0, 2], [ 8, 10]]])
相當于a[::2, ::2, ::2]
1.4 數組的變換
可以將上述三維數組展平:
In[75]: a.flatten() Out[75]: 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])
轉置:
In[77]: b.transpose() Out[77]: array([[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]])
修改shape屬性來改變維度:
In[79]: a.shape = 4, 6 In[80]: a Out[80]: 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]])
1.5 數組的組合
首先創建一個與a同大小的數組:
In[83]: b = 2*a
可以進行多種方式組合,如水平組合:
In[88]: hstack((a, b)) Out[88]: array([[ 0, 1, 2, 3, 4, 5, 0, 2, 4, 6, 8, 10], [ 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22], [12, 13, 14, 15, 16, 17, 24, 26, 28, 30, 32, 34], [18, 19, 20, 21, 22, 23, 36, 38, 40, 42, 44, 46]])
垂直組合:
In[89]: vstack((a, b)) Out[89]: 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], [ 0, 2, 4, 6, 8, 10], [12, 14, 16, 18, 20, 22], [24, 26, 28, 30, 32, 34], [36, 38, 40, 42, 44, 46]])
用concatenate函數可以同時實現這兩種方式,通過指定axis參數,默認為0,使用垂直組合。
還可以進行深度組合:
In[91]: dstack((a, b)) Out[91]: array([[[ 0, 0], [ 1, 2], [ 2, 4], [ 3, 6], [ 4, 8], [ 5, 10]], [[ 6, 12], [ 7, 14], [ 8, 16], [ 9, 18], [10, 20], [11, 22]], [[12, 24], [13, 26], [14, 28], [15, 30], [16, 32], [17, 34]], [[18, 36], [19, 38], [20, 40], [21, 42], [22, 44], [23, 46]]])
就好像將兩張二維平面的點數據沿縱軸方向疊在一起一樣。
1.6 數組的分割
水平分割:
In[94]: hsplit(a, 3) Out[94]: [array([[ 0, 1], [ 6, 7], [12, 13], [18, 19]]), array([[ 2, 3], [ 8, 9], [14, 15], [20, 21]]), array([[ 4, 5], [10, 11], [16, 17], [22, 23]])]
垂直分割:
In[97]: vsplit(a, 2) Out[96]: [array([[ 0, 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11]]), array([[12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23]])]
用split函數可以同時實現這兩個效果,通過設置其axis參數區別。
類似地,可以通過函數dsplit
進行深度分割。
另外可以使用ndarray的一些屬性來查看數組的信息:
In[125]: a.ndim # 維數 Out[124]: 2 In[126]: a.size # 元素總個數 Out[125]: 24 In[127]: a.itemsize # 元素在內存中所占的字節 Out[126]: 4 In[128]: a.shape # 維度 Out[127]: (4, 6) In[130]: a.T # 轉置,相當于transponse函數 Out[129]: array([[ 0, 6, 12, 18], [ 1, 7, 13, 19], [ 2, 8, 14, 20], [ 3, 9, 15, 21], [ 4, 10, 16, 22], [ 5, 11, 17, 23]], dtype=int32)
另外多維數組的flat屬性可以給出一個”扁平迭代器“——flatiter對象,使我們能像一維數組一樣迭代高維數組:
In[134]: for item in array([1, 2, 3, 4]).reshape(2, 2).flat: ... print(item) ... 1 2 3 4
flatiter對象可以直接獲取多個元素,并直接賦值修改:
In[140]: af = a.flat In[141]: af[:] Out[140]: 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], dtype=int32) In[143]: af[3] = 15 In[144]: af[:] Out[143]: array([ 0, 1, 2, 15, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], dtype=int32)
1.7 矩陣的生成
上面提到了可以用二維數組來模擬矩陣,其實,numpy專門提供了一種用于處理矩陣的數據結構——matrix
,它通過mat
函數構造生成:
In[8]: m = mat('1 2 3; 4 5 6; 7 8 9') In[9]: m Out[9]: matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
二維數組與矩陣可以很方便地相互轉換:
In[11]: array(m) Out[11]: array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) In[12]: mat(_) Out[12]: matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
用matrix來處理矩陣更方便,有更多方法以供使用,如:
求逆:
In[17]: m.I Out[17]: 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]])
分塊矩陣:
In[25]: I = eye(3) In[26]: bmat('m I; I m') Out[26]: matrix([[ 1., 2., 3., 1., 0., 0.], [ 4., 5., 6., 0., 1., 0.], [ 7., 8., 9., 0., 0., 1.], [ 1., 0., 0., 1., 2., 3.], [ 0., 1., 0., 4., 5., 6.], [ 0., 0., 1., 7., 8., 9.]])
2 數據處理
2.1 條件判斷和搜索
用where函數可以得到滿足條件的索引,便于后期處理:
In[219]: a = arange(24).reshape(4, 6) In[220]: where(a>8) Out[219]: (array([1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3], dtype=int32), array([3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5], dtype=int32))
用compress
函數可以篩選出一維數組中滿足條件的值:
In[28]: a[0, :].compress(a[0, :] > 2) Out[28]: array([3, 4, 5])
2.2 CSV文件讀寫
CSV(逗號分割值)格式可以簡單方便地保存數組或矩陣。相比于python的pickle方法,保存為CSV文件可以用一般文本編輯器隨時打開查看。保存和讀取CSV文件都很簡單。
In[190]: b Out[189]: array([[ 0, 2, 4, 6, 8, 10], [12, 14, 16, 18, 20, 22], [24, 26, 28, 30, 32, 34], [36, 38, 40, 42, 44, 46]]) In[191]: savetxt("b.txt", b, delimiter=",") In[192]: b1, b2 = loadtxt("b.txt", delimiter=",", usecols=(3, 4), unpack=True) In[193]: b1, b2 Out[192]: (array([ 6., 18., 30., 42.]), array([ 8., 20., 32., 44.]))
保存時參數delimiter
可選,用來分隔數組各元素,讀取時也要相應地指定這個值,讀取時也可只讀取部分數據,usecols
即用來指定選取的列,unpack
設置為True時表示將這些列分開存儲。
讀寫時遇到字符串(如時間)可以通過指定參數converters來轉換。
In[252]: def datestr2num(s): return datetime.datetime.strptime(str(s, encoding="utf-8"), "%Y-%m-%d").date().weekday() weeks, numbers = loadtxt("b.txt", converters={0:datestr2num}, unpack=True) In[253]: weeks Out[252]: array([ 2., 4.])
2.3 通用函數
用frompyfunc
函數可以將一個作用在單一數值的函數映射到作用在數組上的函數:
In[49]: def f(i): ... return 2*i ... In[50]: ff = frompyfunc(f, 1, 1) In[52]: ff(a) Out[52]: array([[0, 2, 4, 6, 8, 10], [12, 14, 16, 18, 20, 22], [24, 26, 28, 30, 32, 34], [36, 38, 40, 42, 44, 46]], dtype=object)
frompyfunc
的兩個參數分別定義輸入參數和輸出參數的個數
另外,numpy提供了一些常用的通用函數,如針對加減乘除的add、subtract、multiply和divide。通用函數都有四個方法:reduce、accumulate、reduceat和outer,以add函數為例:
In[64]: add.reduce(a[0, :]) Out[64]: 15 In[65]: add.accumulate(a[0,:]) Out[65]: array([ 0, 1, 3, 6, 10, 15], dtype=int32) In[69]: add.reduceat(a[0, :], [0, 5, 2, 4]) Out[69]: array([10, 5, 5, 9], dtype=int32) In[70]: add.outer(a[0, :], a[1, :]) Out[70]: array([[ 6, 7, 8, 9, 10, 11], [ 7, 8, 9, 10, 11, 12], [ 8, 9, 10, 11, 12, 13], [ 9, 10, 11, 12, 13, 14], [10, 11, 12, 13, 14, 15], [11, 12, 13, 14, 15, 16]])
可見,reduce是將通用函數遞歸作用在所有元素上,得到最后結果;accumulate也是遞歸作用在所有元素上,不過它保留中間結果并返回;reduceat則根據指定的起始點進行累積運算,如果終點小于起點,則返回終點處的值;最后outer則是對兩個輸入數組的所有元素組合進行運算。
3 科學計算
3.1 統計分析
3.1.1 基本統計分析
average函數可以非常方便地計算加權平均值,或者用mean計算算術平均值:
In[204]: a = array([1, 2]) In[205]: average(a, weights=[1,2]) Out[204]: 1.6666666666666667
基本統計分析函數整理如下:
中位數:median
方差:var
標準差:std
差分:diff
最值:max
、min
、argmax
、argmin
(后兩個得到最值所在的下標)
3.1.2 隨機過程分析
3.2 線性代數
先生成一個各元素是0~1之內的隨機數的矩陣:
In[47]: a = mat(fromiter((random.random() for i in range(9)), dtype = float32).reshape(3, 3)) In[48]: a Out[48]: matrix([[ 0.45035544, 0.53587919, 0.57240343], [ 0.54386997, 0.16267321, 0.97020519], [ 0.6454953 , 0.38505632, 0.94705021]], dtype=float32)
接下我們可以對它進行各種線性代數的操作, 如:
求逆:
In[49]: a.I Out[49]: matrix([[-10.71426678, -14.01229095, 20.83065987], [ 5.42686558, 2.7832334 , -6.13131571], [ 5.09620285, 8.41894722, -10.64905548]], dtype=float32)
解線性方程組(用點積驗證了結果):
In[59]: b = fromiter((random.random() for i in range(3)), dtype = float32) In[60]: b Out[60]: array([ 0.56506187, 0.99419129, 0.70462942], dtype=float32) In[61]: linalg.solve(a, b) Out[61]: array([-5.3072257 , 1.51327574, 3.74607611], dtype=float32) In[63]: dot(a, _) Out[63]: matrix([[ 0.56506193, 0.99419105, 0.70462948]], dtype=float32)
求特征值和特征向量:
In[64]: linalg.eig(a) Out[64]: (array([ 1.78036737, -0.08517434, -0.13511421], dtype=float32), matrix([[-0.5075314 , -0.82206506, 0.77804375], [-0.56222379, 0.4528676 , -0.57155234], [-0.65292901, 0.34513769, -0.26072171]], dtype=float32))
行列式:
In[81]: linalg.det(a) Out[81]: 0.020488938
關于“Python中numpy有什么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。