NumPy的主要對象是同質的多維數組。它是一個有明確索引的相同類型的元素組成的表。在NumPy中維度稱之爲軸,軸數稱之爲列。html
舉個例子:python
例一:算法
[ 1, 2, 1 ]數組
這是一個一維數組,由於它只有一個軸,這個軸的長度是3.dom
列二:ide
[[ 1., 0., 0.],[ 0., 1., 2.]]
這是一個二維數組,第一個維度的長度是2,第二個維度的長度是3.
ui
NumPy中的array類被稱之爲ndarray,可是他的別名array更有名。特別須要注意的是NumPy.array和Python 標準庫裏的arry.array不同。array.array只提供了比較少的方法。而NumPy中array包含如下重要屬性:lua
ndarray.ndimspa
數組的維度數量
htm
返回類型: number
ndarray.shape
數組的各個維度,這是一個存儲了數組各個維度大小的int類型元祖。是一個n行m列矩陣,shape(n,m),這個shape的長度就是數組的維度數量。(如(2,3)表示2x3)
返回類型:tuple
ndarray.size
數組中全部元素的數量
返回類型:number
ndarray.dtype
數組中元素的類型。你可使用python的types來建立和指定dtype’s,除此以外,numpy有本身的types,如:float64
返回類型:dtype對象
ndarray.itemsize
數組中每一個元素的字節數。例如:float64類型的數組元素的itemize是8(64/8)
ndarray.data
不經常使用,訪問數組元素使用索引更便利
建立數組
#使用array方法建立數組,array的參數能夠是python的list和tuple >>> 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')
#array能夠將序列中的序列轉化爲2維數組 >>> b = np.array([(1.5,2,3), (4,5,6)]) >>> b array([[ 1.5, 2. , 3. ], [ 4. , 5. , 6. ]])
數組的類型能夠在建立時被顯示的指定 >>> c = np.array( [ [1,2], [3,4] ], dtype=complex ) >>> c array([[ 1.+0.j, 2.+0.j], [ 3.+0.j, 4.+0.j]])
在建立數組的時候一般不知道數組的數據,可是知道數組的大小。因此numpy提供了幾種方式類初始化數組內容。
zeros建立一個全部元素都是0的數組
>>> np.zeros( (3,4) ) array([[ 0., 0., 0., 0.], [ 0., 0., 0., 0.], [ 0., 0., 0., 0.]])
ones建立一個全部元素都是1的數組
>>> 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)
empty的內容使用隨機數填充
>>> 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]])
連續的數字使用range(start, end, step)生成數組
>>> 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])
因爲浮點型涉及到字符精度,因此不拿呢個使用range,而是使用linspace替代
>>> from numpy import pi >>> np.linspace( 0, 2, 9 ) # 9 numbers from 0 to 2 array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ]) >>> x = np.linspace( 0, 2*pi, 100 ) # useful to evaluate function at lots of points >>> f = np.sin(x)
reshape輸出隊列的格式
>>> a = np.arange(6) # 默認是一維數組 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]]
下面是數組的基本操做
>>> a = np.array( [20,30,40,50] ) >>> b = np.arange( 4 ) >>> b #輸b的內容,便於觀察c的結果 array([0, 1, 2, 3]) >>> c = a-b #數組相減 >>> c array([20, 29, 38, 47]) >>> b**2 #b的二次冪 array([0, 1, 4, 9]) >>> 10*np.sin(a) #數組a中每一個值的正玄值的10倍 array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854]) >>> a<35 #數組a中的數值是否比35小 array([ True, True, False, False], dtype=bool)
特別須要注意的是數組的乘法和數組的矩陣計算方式不一樣。* 的計算方式是對應位置的數字相乘。而矩陣的算法,詳見連接
>>> A = np.array( [[1,1] ,... [0,1]] ) >>> B = np.array( [[2,0], ... [3,4]] ) >>> A*B # elementwise product array([[2, 0], [0, 4]]) >>> A.dot(B) # matrix product array([[5, 4], [3, 4]]) >>> np.dot(A, B) # another matrix product array([[5, 4], [3, 4]])
使用+=,*=來修改當前的數組,比建立數組更節省內存
>>> a = np.ones((2,3), dtype=int) >>> b = np.random.random((2,3)) >>> a *= 3 >>> aarray([[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沒法自動轉換成int類型 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int16') with casting rule 'same_kind'
數據類型不一樣的倆個或多個數組進行操做,結果會向上趨於精度更高的一方
>>> a = np.ones(3, dtype=np.int32) >>> b = np.linspace(0,pi,3) >>> b.dtype.name 'float64' >>> c = a+b >>> carray([ 1. , 2.57079633, 4.14159265]) >>> c.dtype.name #b的精度更高,因此結果c和b是同一類型 'float64' >>> d = np.exp(c*1j) >>> darray([ 0.54030231+0.84147098j, -0.84147098+0.54030231j, -0.54030231-0.84147098j]) >>> d.dtype.name 'complex128'
ndarray還提供了不少的數學操做如:random,sum,max,min等
>>> 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
你能夠指定多維數組的特定維度進行計算
>>> 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
>>> B = np.arange(3) >>> Barray([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.])
數組的索引,切片和迭代
>>> 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]])
若是維數太多的話可使用...來替代。
>>>c = np.array( [[[ 0, 1, 2], [ 10, 12, 13]], [[100,101,102], [110,112,113]]]) >>> c.shape #共有三個維度,0維2個元素,1維2個元素,2維3個元素 (2, 2, 3) >>> c[1,...] #0維索引爲1的元素,相似於list的get(1) array([[100, 101, 102], [110, 112, 113]]) >>>c[...,2] #前面的...表示0維和1維,最後的數字表是2維的索引爲2的元素 array([[ 2, 13], [102, 113]])
迭代數組元素
>>> for row in b: #迭代數組輸出維度維0的元素信息 print(b) >>> for element in b.flat: #輸出數組的每個元素 print(element)
改變數組的形狀
>>> 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() #扁平話處理,及只有一個維度 array([ 2., 8., 0., 6., 4., 5., 1., 1., 8., 9., 3., 6.]) >>> a.reshape(6,2) #改變形狀爲6行2列形式 array([[ 2., 8.], [ 0., 6.], [ 4., 5.], [ 1., 1.], [ 8., 9.], [ 3., 6.]]) >>> a.T #換位,即行變成列,列變成行 array([[ 2., 4., 8.], [ 8., 5., 9.], [ 0., 1., 3.], [ 6., 1., 6.]]) >>> a.T.shape (4, 3) >>> a.shape (3, 4) reshape改變了數組的形狀,新生乘了一個數組,可是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.]]) 合併數組:橫向合併和縱向合併 >>> 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.]]) column_stack合併數組,值合併第一維度 >>> from numpy import newaxis >>> np.column_stack((a,b)) # With 2D arrays array([[ 8., 8., 1., 8.], [ 0., 0., 0., 4.]]) >>> a = np.array([4.,2.]) >>> b = np.array([2.,8.]) >>> a[:,newaxis] # This allows to have a 2D columns vector array([[ 4.], [ 2.]]) >>> np.column_stack((a[:,newaxis],b[:,newaxis])) #合併2維數組 array([[ 4., 2.], [ 2., 8.]]) >>> np.vstack((a[:,newaxis],b[:,newaxis])) array([[ 4.], [ 2.], [ 2.], [ 8.]]) 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 切割成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.]])] array_split能夠自定義切割的水平方向哈市垂直方向 >>> x = np.arange(8.0) >>> np.array_split(x, 3) #array_split(ary, indices_or_sections, axis=0) [array([ 0., 1., 2.]), array([ 3., 4., 5.]), array([ 6., 7.])] 複製 簡單的賦值,b指向a的對象 >>> 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) 快照模式 >>> 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]]) 深度拷貝 >>> 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]])