NumPy是Python中科學計算的基礎包。它是一個Python庫,提供多維數組對象,各類派生對象(如掩碼數組和矩陣),以及用於數組快速操做的各類API,有包括數學、邏輯、形狀操做、排序、選擇、輸入輸出、離散傅立葉變換、基本線性代數,基本統計運算和隨機模擬等等。html
NumPy包的核心是 ndarray 對象。它封裝了python原生的同數據類型的 n 維數組,爲了保證其性能優良,其中有許多操做都是代碼在本地進行編譯後執行的。python
NumPy數組 和 原生Python Array(數組)之間有幾個重要的區別:數組
shape
將是 (n,m)
。所以,shape
元組的長度就是rank或維度的個數 ndim
。shape
的元素的乘積。float64
類型的數組的 itemsize
爲8(=64/8),而 complex32
類型的數組的 itemsize
爲4(=32/8)。它等於 ndarray.dtype.itemsize
。一個例子less
>>> import numpy as np >>> a = np.arange(15).reshape(3, 5) >>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> a.shape (3, 5) >>> a.ndim 2 >>> a.dtype.name 'int64' >>> a.itemsize 8 >>> a.size 15 >>> type(a) <type 'numpy.ndarray'> >>> b = np.array([6, 7, 8]) >>> b array([6, 7, 8]) >>> type(b) <type 'numpy.ndarray'>
有幾種方法能夠建立數組。dom
例如,你可使用array函數從常規Python列表或元組中建立數組。獲得的數組的類型是從Python列表中元素的類型推導出來的。ide
>>> import numpy as np >>> a = np.array([2,3,4]) >>> a array([2, 3, 4]) >>> a.dtype dtype('int64') >>> b = np.array([1.2, 3.5, 5.1]) >>> b.dtype dtype('float64')
能夠在建立時顯式指定數組的類型:函數
>>> c = np.array( [ [1,2], [3,4] ], dtype=complex ) >>> c array([[ 1.+0.j, 2.+0.j], [ 3.+0.j, 4.+0.j]])
函數zeros
建立一個由0組成的數組,函數 ones
建立一個完整的數組,函數empty
建立一個數組,其初始內容是隨機的,取決於內存的狀態。默認狀況下,建立的數組的dtype是 float64
類型的。工具
>>> np.zeros( (3,4) ) array([[ 0., 0., 0., 0.], [ 0., 0., 0., 0.], [ 0., 0., 0., 0.]]) >>> np.ones( (2,3,4), dtype=np.int16 ) # dtype can also be specified array([[[ 1, 1, 1, 1], [ 1, 1, 1, 1], [ 1, 1, 1, 1]], [[ 1, 1, 1, 1], [ 1, 1, 1, 1], [ 1, 1, 1, 1]]], dtype=int16) >>> np.empty( (2,3) ) # uninitialized, output may vary array([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260], [ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])
爲了建立數字組成的數組,NumPy提供了一個相似於range
的函數,該函數返回數組而不是列表。佈局
>>> np.arange( 10, 30, 5 ) array([10, 15, 20, 25]) >>> np.arange( 0, 2, 0.3 ) # it accepts float arguments array([ 0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])
當您打印數組時,NumPy以與嵌套列表相似的方式顯示它,但具備如下佈局:性能
而後將一維數組打印爲行,將二維數據打印爲矩陣,將三維數據打印爲矩數組表。
>>> a = np.arange(6) # 1d array >>> print(a) [0 1 2 3 4 5] >>> >>> b = np.arange(12).reshape(4,3) # 2d array >>> print(b) [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] >>> >>> c = np.arange(24).reshape(2,3,4) # 3d array >>> print(c) [[[ 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 = np.array( [20,30,40,50] ) >>> b = np.arange( 4 ) >>> b array([0, 1, 2, 3]) >>> c = a-b >>> c array([20, 29, 38, 47]) >>> b**2 array([0, 1, 4, 9]) >>> 10*np.sin(a) array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854]) >>> a<35 array([ True, True, False, False])
與許多矩陣語言不一樣,乘積運算符*
在NumPy數組中按元素進行運算。矩陣乘積可使用@
運算符(在python> = 3.5中)或dot
函數或方法執行:
>>> A = np.array( [[1,1], ... [0,1]] ) >>> B = np.array( [[2,0], ... [3,4]] ) >>> A * B # elementwise product array([[2, 0], [0, 4]]) >>> A @ B # matrix product array([[5, 4], [3, 4]]) >>> A.dot(B) # another matrix product array([[5, 4], [3, 4]])
某些操做(例如+=
和 *=
)會更直接更改被操做的矩陣數組而不會建立新矩陣數組。
>>> a = np.ones((2,3), dtype=int) >>> b = np.random.random((2,3)) >>> a *= 3 >>> a array([[3, 3, 3], [3, 3, 3]]) >>> b += a >>> b array([[ 3.417022 , 3.72032449, 3.00011437], [ 3.30233257, 3.14675589, 3.09233859]]) >>> a += b # b is not automatically converted to integer type Traceback (most recent call last): ... TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
許多一元操做,例如計算數組中全部元素的總和,都是做爲ndarray
類的方法實現的。
>>> a = np.random.random((2,3)) >>> a array([[ 0.18626021, 0.34556073, 0.39676747], [ 0.53881673, 0.41919451, 0.6852195 ]]) >>> a.sum() 2.5718191614547998 >>> a.min() 0.1862602113776709 >>> a.max() 0.6852195003967595
默認狀況下,這些操做適用於數組,就像它是一個數字列表同樣,不管其形狀如何。可是,經過指定axis
參數,您能夠沿數組的指定軸應用操做:
>>> b = np.arange(12).reshape(3,4) >>> b array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> >>> b.sum(axis=0) # sum of each column array([12, 15, 18, 21]) >>> >>> b.min(axis=1) # min of each row array([0, 4, 8]) >>> >>> b.cumsum(axis=1) # cumulative sum along each row array([[ 0, 1, 3, 6], [ 4, 9, 15, 22], [ 8, 17, 27, 38]])
NumPy提供熟悉的數學函數,例如sin,cos和exp。在NumPy中,這些被稱爲「通函數」(ufunc
)。在NumPy中,這些函數在數組上按元素進行運算,產生一個數組做爲輸出。
>>> B = np.arange(3) >>> B array([0, 1, 2]) >>> np.exp(B) array([ 1. , 2.71828183, 7.3890561 ]) >>> np.sqrt(B) array([ 0. , 1. , 1.41421356]) >>> C = np.array([2., -1., 4.]) >>> np.add(B, C) array([ 2., 0., 6.])
一維的數組能夠進行索引、切片和迭代操做的,就像 列表 和其餘Python序列類型同樣。
>>> a = np.arange(10)**3 >>> a array([ 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]) >>> a[2] 8 >>> a[2:5] array([ 8, 27, 64]) >>> a[:6:2] = -1000 # equivalent to a[0:6:2] = -1000; from start to position 6, exclusive, set every 2nd element to -1000 >>> a array([-1000, 1, -1000, 27, -1000, 125, 216, 343, 512, 729]) >>> a[ : :-1] # reversed a array([ 729, 512, 343, 216, 125, -1000, 27, -1000, 1, -1000]) >>> for i in a: ... print(i**(1/3.)) ... nan 1.0 nan 3.0 nan 5.0 6.0 7.0 8.0 9.0
多維的數組每一個軸能夠有一個索引。這些索引以逗號分隔的元組給出:
>>> def f(x,y): ... return 10*x+y ... >>> b = np.fromfunction(f,(5,4),dtype=int) >>> b array([[ 0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23], [30, 31, 32, 33], [40, 41, 42, 43]]) >>> b[2,3] 23 >>> b[0:5, 1] # each row in the second column of b array([ 1, 11, 21, 31, 41]) >>> b[ : ,1] # equivalent to the previous example array([ 1, 11, 21, 31, 41]) >>> b[1:3, : ] # each column in the second and third row of b array([[10, 11, 12, 13], [20, 21, 22, 23]])
當提供的索引少於軸的數量時,缺失的索引被認爲是完整的切片:
>>> b[-1] # the last row. Equivalent to b[-1,:] array([40, 41, 42, 43])
b[i]
方括號中的表達式 i
被視爲後面緊跟着 :
的多個實例,用於表示剩餘軸。NumPy也容許你使用三個點寫爲 b[i,...]
。
三個點( ...
)表示產生完整索引元組所需的冒號。例如,若是 x
是rank爲的5數組(即,它具備5個軸),則:
x[1,2,...]
至關於 x[1,2,:,:,:]
,x[...,3]
等效於 x[:,:,:,:,3]
x[4,...,5,:]
等效於 x[4,:,:,5,:]
。>>> c = np.array( [[[ 0, 1, 2], # a 3D array (two stacked 2D arrays) ... [ 10, 12, 13]], ... [[100,101,102], ... [110,112,113]]]) >>> c.shape (2, 2, 3) >>> c[1,...] # same as c[1,:,:] or c[1] array([[100, 101, 102], [110, 112, 113]]) >>> c[...,2] # same as c[:,:,2] array([[ 2, 13], [102, 113]])
對多維數組進行 迭代(Iterating) 是相對於第一個軸完成的:
>>> for row in b: ... print(row) ... [0 1 2 3] [10 11 12 13] [20 21 22 23] [30 31 32 33] [40 41 42 43]
可是,若是想要對數組中的每一個元素執行操做,可使用flat
屬性,該屬性是數組的全部元素的迭代器:
>>> for element in b.flat: ... print(element) ... 0 1 2 3 10 11 12 13 20 21 22 23 30 31 32 33 40 41 42 43
一個數組的形狀是由每一個軸的元素數量決定的:
>>> a = np.floor(10*np.random.random((3,4))) >>> a array([[ 2., 8., 0., 6.], [ 4., 5., 1., 1.], [ 8., 9., 3., 6.]]) >>> a.shape (3, 4)
可使用各類命令更改數組的形狀。請注意,如下三個命令都返回一個修改後的數組,但不會更改原始數組:
>>> a.ravel() # returns the array, flattened array([ 2., 8., 0., 6., 4., 5., 1., 1., 8., 9., 3., 6.]) >>> a.reshape(6,2) # returns the array with a modified shape array([[ 2., 8.], [ 0., 6.], [ 4., 5.], [ 1., 1.], [ 8., 9.], [ 3., 6.]]) >>> a.T # returns the array, transposed array([[ 2., 4., 8.], [ 8., 5., 9.], [ 0., 1., 3.], [ 6., 1., 6.]]) >>> a.T.shape (4, 3) >>> a.shape (3, 4)
由 ravel() 產生的數組中元素的順序一般是「C風格」,也就是說,最右邊的索引「變化最快」,所以[0,0]以後的元素是[0,1] 。若是將數組從新整形爲其餘形狀,則該數組將被視爲「C風格」。NumPy一般建立按此順序存儲的數組,所以 ravel() 一般不須要複製其參數,但若是數組是經過獲取另外一個數組的切片或使用不常見的選項建立的,則可能須要複製它。還可使用可選參數指示函數 ravel() 和 reshape(),以使用FORTRAN樣式的數組,其中最左邊的索引變化最快。
該reshape
函數返回帶有修改形狀的參數,而該 ndarray.resize
方法會修改數組自己:
>>> a array([[ 2., 8., 0., 6.], [ 4., 5., 1., 1.], [ 8., 9., 3., 6.]]) >>> a.resize((2,6)) >>> a array([[ 2., 8., 0., 6., 4., 5.], [ 1., 1., 8., 9., 3., 6.]])
若是在 reshape 操做中將 size 指定爲-1,則會自動計算其餘的 size 大小:
>>> a.reshape(3,-1) array([[ 2., 8., 0., 6.], [ 4., 5., 1., 1.], [ 8., 9., 3., 6.]])
幾個數組能夠沿不一樣的軸堆疊在一塊兒,例如:
>>> a = np.floor(10*np.random.random((2,2))) >>> a array([[ 8., 8.], [ 0., 0.]]) >>> b = np.floor(10*np.random.random((2,2))) >>> b array([[ 1., 8.], [ 0., 4.]]) >>> np.vstack((a,b)) array([[ 8., 8.], [ 0., 0.], [ 1., 8.], [ 0., 4.]]) >>> np.hstack((a,b)) array([[ 8., 8., 1., 8.], [ 0., 0., 0., 4.]])
使用hsplit
,能夠沿數組的水平軸拆分數組,方法是指定要返回的形狀相等的數組的數量,或者指定應該在其以後進行分割的列:
>>> a = np.floor(10*np.random.random((2,12))) >>> a array([[ 9., 5., 6., 3., 6., 8., 0., 7., 9., 7., 2., 7.], [ 1., 4., 9., 2., 2., 1., 0., 6., 2., 2., 4., 0.]]) >>> np.hsplit(a,3) # Split a into 3 [array([[ 9., 5., 6., 3.], [ 1., 4., 9., 2.]]), array([[ 6., 8., 0., 7.], [ 2., 1., 0., 6.]]), array([[ 9., 7., 2., 7.], [ 2., 2., 4., 0.]])] >>> np.hsplit(a,(3,4)) # Split a after the third and the fourth column [array([[ 9., 5., 6.], [ 1., 4., 9.]]), array([[ 3.], [ 2.]]), array([[ 6., 8., 0., 7., 9., 7., 2., 7.], [ 2., 1., 0., 6., 2., 2., 4., 0.]])]
vsplit沿垂直軸分割,並array_split容許指定要分割的軸。
當計算和操做數組時,有時會將數據複製到新數組中,有時則不會。這一般是初學者混淆的根源。有三種狀況:
簡單分配不會複製數組對象或其數據。
>>> a = np.arange(12) >>> b = a # no new object is created >>> b is a # a and b are two names for the same ndarray object True >>> b.shape = 3,4 # changes the shape of a >>> a.shape (3, 4)
Python將可變對象做爲引用傳遞,所以函數調用不會複製。
>>> def f(x): ... print(id(x)) ... >>> id(a) # id is a unique identifier of an object 148293216 >>> f(a) 148293216
不一樣的數組對象能夠共享相同的數據。該view
方法建立一個查看相同數據的新數組對象。
>>> c = a.view() >>> c is a False >>> c.base is a # c is a view of the data owned by a True >>> c.flags.owndata False >>> >>> c.shape = 2,6 # a's shape doesn't change >>> a.shape (3, 4) >>> c[0,4] = 1234 # a's data changes >>> a array([[ 0, 1, 2, 3], [1234, 5, 6, 7], [ 8, 9, 10, 11]])
切片數組會返回一個視圖
>>> s = a[ : , 1:3] # spaces added for clarity; could also be written "s = a[:,1:3]" >>> s[:] = 10 # s[:] is a view of s. Note the difference between s=10 and s[:]=10 >>> a array([[ 0, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]])
該copy
方法生成數組及其數據的完整副本。
>>> d = a.copy() # a new array object with new data is created >>> d is a False >>> d.base is a # d doesn't share anything with a False >>> d[0,0] = 9999 >>> a array([[ 0, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]])
有時,若是再也不須要原始數組,則應在切片後調用 copy
。例如,假設a是一個巨大的中間結果,最終結果b只包含a的一小部分,那麼在用切片構造b時應該作一個深拷貝:
>>> a = np.arange(int(1e8)) >>> b = a[:100].copy() >>> del a # the memory of ``a`` can be released.
若是改成使用 b = a[:100]
,則 a
由 b
引用,而且即便執行 del a
也會在內存中持久存在。
廣播容許通用功能以有意義的方式處理不具備徹底相同形狀的輸入。
廣播的第一個規則是,若是全部輸入數組不具備相同數量的維度,則將「1」重複地預先添加到較小數組的形狀,直到全部數組具備相同數量的維度。
廣播的第二個規則確保沿特定維度的大小爲1的數組表現爲具備沿該維度具備最大形狀的數組的大小。假定數組元素的值沿着「廣播」數組的那個維度是相同的。
應用廣播規則後,全部數組的大小必須匹配。更多細節能夠在廣播中找到。
NumPy提供比常規Python序列更多的索引功能。除了經過整數和切片進行索引以外,正如咱們以前看到的,數組能夠由整數數組和布爾數組索引。
>>> a = np.arange(12)**2 # the first 12 square numbers >>> i = np.array( [ 1,1,3,8,5 ] ) # an array of indices >>> a[i] # the elements of a at the positions i array([ 1, 1, 9, 64, 25]) >>> >>> j = np.array( [ [ 3, 4], [ 9, 7 ] ] ) # a bidimensional array of indices >>> a[j] # the same shape as j array([[ 9, 16], [81, 49]])
當索引數組a
是多維的時,單個索引數組指的是第一個維度a
。如下示例經過使用調色板將標籤圖像轉換爲彩色圖像來顯示此行爲。
>>> palette = np.array( [ [0,0,0], # black ... [255,0,0], # red ... [0,255,0], # green ... [0,0,255], # blue ... [255,255,255] ] ) # white >>> image = np.array( [ [ 0, 1, 2, 0 ], # each value corresponds to a color in the palette ... [ 0, 3, 4, 0 ] ] ) >>> palette[image] # the (2,4,3) color image array([[[ 0, 0, 0], [255, 0, 0], [ 0, 255, 0], [ 0, 0, 0]], [[ 0, 0, 0], [ 0, 0, 255], [255, 255, 255], [ 0, 0, 0]]])
咱們還能夠爲多個維度提供索引。每一個維度的索引數組必須具備相同的形狀。
>>> a = np.arange(12).reshape(3,4) >>> a array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> i = np.array( [ [0,1], # indices for the first dim of a ... [1,2] ] ) >>> j = np.array( [ [2,1], # indices for the second dim ... [3,3] ] ) >>> >>> a[i,j] # i and j must have equal shape array([[ 2, 5], [ 7, 11]]) >>> >>> a[i,2] array([[ 2, 6], [ 6, 10]]) >>> >>> a[:,j] # i.e., a[ : , j] array([[[ 2, 1], [ 3, 3]], [[ 6, 5], [ 7, 7]], [[10, 9], [11, 11]]])
固然,咱們能夠按順序(好比列表)放入i
,j
而後使用列表進行索引。
>>> l = [i,j] >>> a[l] # equivalent to a[i,j] array([[ 2, 5], [ 7, 11]])
可是,咱們不能經過放入i
和j
放入數組來實現這一點,由於這個數組將被解釋爲索引a的第一個維度。
>>> s = np.array( [i,j] ) >>> a[s] # not what we want Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: index (3) out of range (0<=index<=2) in dimension 0 >>> >>> a[tuple(s)] # same as a[i,j] array([[ 2, 5], [ 7, 11]])
使用數組索引的另外一個常見用法是搜索與時間相關的系列的最大值:
>>> time = np.linspace(20, 145, 5) # time scale >>> data = np.sin(np.arange(20)).reshape(5,4) # 4 time-dependent series >>> time array([ 20. , 51.25, 82.5 , 113.75, 145. ]) >>> data array([[ 0. , 0.84147098, 0.90929743, 0.14112001], [-0.7568025 , -0.95892427, -0.2794155 , 0.6569866 ], [ 0.98935825, 0.41211849, -0.54402111, -0.99999021], [-0.53657292, 0.42016704, 0.99060736, 0.65028784], [-0.28790332, -0.96139749, -0.75098725, 0.14987721]]) >>> >>> ind = data.argmax(axis=0) # index of the maxima for each series >>> ind array([2, 0, 3, 1]) >>> >>> time_max = time[ind] # times corresponding to the maxima >>> >>> data_max = data[ind, range(data.shape[1])] # => data[ind[0],0], data[ind[1],1]... >>> >>> time_max array([ 82.5 , 20. , 113.75, 51.25]) >>> data_max array([ 0.98935825, 0.84147098, 0.99060736, 0.6569866 ]) >>> >>> np.all(data_max == data.max(axis=0)) True
您還可使用數組索引做爲分配給的目標:
>>> a = np.arange(5) >>> a array([0, 1, 2, 3, 4]) >>> a[[1,3,4]] = 0 >>> a array([0, 0, 2, 0, 0])
可是,當索引列表包含重複時,分配會屢次完成,留下最後一個值:
>>> a = np.arange(5) >>> a[[0,0,2]]=[1,2,3] >>> a array([2, 1, 3, 3, 4])
這是合理的,但請注意是否要使用Python的 +=
構造,由於它可能不會按預期執行:
>>> a = np.arange(5) >>> a[[0,0,2]]+=1 >>> a array([1, 1, 3, 3, 4])
即便0在索引列表中出現兩次,第0個元素也只增長一次。這是由於Python要求「a + = 1」等同於「a = a + 1」。
當咱們使用(整數)索引數組索引數組時,咱們提供了要選擇的索引列表。使用布爾索引,方法是不一樣的; 咱們明確地選擇咱們想要的數組中的哪些項目以及咱們不須要的項目。
人們能夠想到的最天然的布爾索引方法是使用與原始數組具備 相同形狀的 布爾數組:
>>> a = np.arange(12).reshape(3,4) >>> b = a > 4 >>> b # b is a boolean with a's shape array([[False, False, False, False], [False, True, True, True], [ True, True, True, True]]) >>> a[b] # 1d array with the selected elements array([ 5, 6, 7, 8, 9, 10, 11])
此屬性在分配中很是有用:
>>> a[b] = 0 # All elements of 'a' higher than 4 become 0 >>> a array([[0, 1, 2, 3], [4, 0, 0, 0], [0, 0, 0, 0]])
您能夠查看如下示例,瞭解如何使用布爾索引生成Mandelbrot集的圖像:
>>> import numpy as np >>> import matplotlib.pyplot as plt >>> def mandelbrot( h,w, maxit=20 ): ... """Returns an image of the Mandelbrot fractal of size (h,w).""" ... y,x = np.ogrid[ -1.4:1.4:h*1j, -2:0.8:w*1j ] ... c = x+y*1j ... z = c ... divtime = maxit + np.zeros(z.shape, dtype=int) ... ... for i in range(maxit): ... z = z**2 + c ... diverge = z*np.conj(z) > 2**2 # who is diverging ... div_now = diverge & (divtime==maxit) # who is diverging now ... divtime[div_now] = i # note when ... z[diverge] = 2 # avoid diverging too much ... ... return divtime >>> plt.imshow(mandelbrot(400,400)) >>> plt.show()
使用布爾值進行索引的第二種方法更相似於整數索引; 對於數組的每一個維度,咱們給出一個1D布爾數組,選擇咱們想要的切片:
>>> a = np.arange(12).reshape(3,4) >>> b1 = np.array([False,True,True]) # first dim selection >>> b2 = np.array([True,False,True,False]) # second dim selection >>> >>> a[b1,:] # selecting rows array([[ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> >>> a[b1] # same thing array([[ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> >>> a[:,b2] # selecting columns array([[ 0, 2], [ 4, 6], [ 8, 10]]) >>> >>> a[b1,b2] # a weird thing to do array([ 4, 10])
請注意,1D布爾數組的長度必須與要切片的尺寸(或軸)的長度一致。在前面的例子中,b1
具備長度爲3(的數目 的行 中a
),和 b2
(長度4)適合於索引的第二軸線(列) a
。
ix_
函數可用於組合不一樣的向量,以便得到每一個n-uplet的結果。例如,若是要計算從每一個向量a,b和c中取得的全部三元組的全部a + b * c:
>>> a = np.array([2,3,4,5]) >>> b = np.array([8,5,4]) >>> c = np.array([5,4,6,8,3]) >>> ax,bx,cx = np.ix_(a,b,c) >>> ax array([[[2]], [[3]], [[4]], [[5]]]) >>> bx array([[[8], [5], [4]]]) >>> cx array([[[5, 4, 6, 8, 3]]]) >>> ax.shape, bx.shape, cx.shape ((4, 1, 1), (1, 3, 1), (1, 1, 5)) >>> result = ax+bx*cx >>> result array([[[42, 34, 50, 66, 26], [27, 22, 32, 42, 17], [22, 18, 26, 34, 14]], [[43, 35, 51, 67, 27], [28, 23, 33, 43, 18], [23, 19, 27, 35, 15]], [[44, 36, 52, 68, 28], [29, 24, 34, 44, 19], [24, 20, 28, 36, 16]], [[45, 37, 53, 69, 29], [30, 25, 35, 45, 20], [25, 21, 29, 37, 17]]]) >>> result[3,2,4] 17 >>> a[3]+b[2]*c[4] 17
還能夠按以下方式實現reduce:
>>> def ufunc_reduce(ufct, *vectors): ... vs = np.ix_(*vectors) ... r = ufct.identity ... for v in vs: ... r = ufct(r,v) ... return r
而後將其用做:
>>> ufunc_reduce(np.add,a,b,c) array([[[15, 14, 16, 18, 13], [12, 11, 13, 15, 10], [11, 10, 12, 14, 9]], [[16, 15, 17, 19, 14], [13, 12, 14, 16, 11], [12, 11, 13, 15, 10]], [[17, 16, 18, 20, 15], [14, 13, 15, 17, 12], [13, 12, 14, 16, 11]], [[18, 17, 19, 21, 16], [15, 14, 16, 18, 13], [14, 13, 15, 17, 12]]])
與普通的ufunc.reduce相比,這個版本的reduce的優勢是它利用了廣播規則 ,以免建立一個參數數組,輸出的大小乘以向量的數量。
>>> import numpy as np >>> a = np.array([[1.0, 2.0], [3.0, 4.0]]) >>> print(a) [[ 1. 2.] [ 3. 4.]] >>> a.transpose() array([[ 1., 3.], [ 2., 4.]]) >>> np.linalg.inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> u = np.eye(2) # unit 2x2 matrix; "eye" represents "I" >>> u array([[ 1., 0.], [ 0., 1.]]) >>> j = np.array([[0.0, -1.0], [1.0, 0.0]]) >>> j @ j # matrix product array([[-1., 0.], [ 0., -1.]]) >>> np.trace(u) # trace 2.0 >>> y = np.array([[5.], [7.]]) >>> np.linalg.solve(a, y) array([[-3.], [ 4.]]) >>> np.linalg.eig(j) (array([ 0.+1.j, 0.-1.j]), array([[ 0.70710678+0.j , 0.70710678-0.j ], [ 0.00000000-0.70710678j, 0.00000000+0.70710678j]]))
Parameters: square matrix Returns The eigenvalues, each repeated according to its multiplicity. The normalized (unit "length") eigenvectors, such that the column ``v[:,i]`` is the eigenvector corresponding to the eigenvalue ``w[i]`` .
這裏咱們列出一些簡短有用的提示。
要更改數組的尺寸,您能夠省略其中一個尺寸,而後自動推導出尺寸:
>>> a = np.arange(30) >>> a.shape = 2,-1,3 # -1 means "whatever is needed" >>> a.shape (2, 5, 3) >>> 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], [24, 25, 26], [27, 28, 29]]])
咱們如何從同等大小的行向量列表中構造一個二維數組?在MATLAB這是很簡單:若是x
和y
你只須要作兩個相同長度的向量m=[x;y]
。在此NumPy的經過功能的工做原理column_stack
,dstack
,hstack
和vstack
,視維在堆疊是必需要作的。例如:
x = np.arange(0,10,2) # x=([0,2,4,6,8]) y = np.arange(5) # y=([0,1,2,3,4]) m = np.vstack([x,y]) # m=([[0,2,4,6,8], # [0,1,2,3,4]]) xy = np.hstack([x,y]) # xy =([0,2,4,6,8,0,1,2,3,4])
這些函數背後的邏輯在兩個以上的維度上可能很奇怪。
histogram
應用於數組的NumPy 函數返回一對向量:數組的直方圖和bin的向量。注意: matplotlib
還有一個構建直方圖的功能(hist
在Matlab中稱爲),與NumPy中的直方圖不一樣。主要區別在於pylab.hist
自動繪製直方圖,而 numpy.histogram
只生成數據。
>>> import numpy as np >>> import matplotlib.pyplot as plt >>> # Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2 >>> mu, sigma = 2, 0.5 >>> v = np.random.normal(mu,sigma,10000) >>> # Plot a normalized histogram with 50 bins >>> plt.hist(v, bins=50, density=1) # matplotlib version (plot) >>> plt.show()
>>> # Compute the histogram with numpy and then plot it >>> (n, bins) = np.histogram(v, bins=50, density=True) # NumPy version (no plot) >>> plt.plot(.5*(bins[1:]+bins[:-1]), n) >>> plt.show()