本文乃Numpy Quickstart tutorial的翻譯版本(並非完全翻譯,翻譯君爲本人),英語能力足夠的童鞋請閱讀原文~,如果您覺得本文對您有幫助的話不要忘記點個贊哦!
一 預先準備
在閱讀本文之前,請先確保您已經有了一些python基礎,如果沒有的話,請看Python Tutorial,安裝在此跳過。
二 基礎
numpy的操作對象通常是齊次的多維數組,數組的每一個元素的類型應當一致(比如全爲int,float等等),numpy中,多維數組的維度被稱爲軸(比如三維數組之於XYZ),軸上以循秩(rank)訪問。
譬如在三維空間中一個點[1,2,1],該點的座標可以看做是一個rank爲1的數組(一維數組),數組長度3
而下列所示爲rank=2(二維數組),第一個維度長度爲2,第二個維度長度爲3
[[ 1., 0., 0.],
[ 0., 1., 2.]]
Numpy的數組類稱爲ndarray,注意numpy.array和python標準庫中的array並不一樣,後者只提供一維數組及其操作。下面列出numpy的一些重要接口:
ndarray.ndim
數組的維度,也稱數組的軸(axes)的數量。
ndarray.shape
數組的尺寸。返回一個整數元組,表示數組中每個維度上,數組含有多少元素。對於具有n行m列的矩陣,形狀將是(n,m)。顯然這個元組的長度是數組的維度ndarray.ndim
ndarray.size
數組元素的總數。等於數組尺寸中所有值的乘積,對於具有n行m列的矩陣,就是n*m
ndarray.dtype
數組中元素的類型。可以使用標準的Python中定義的類型創建,或指定其他的dtype類型。此外,NumPy提供了一些它自己的類型。譬如: numpy.int32,numpy.int16,numpy.float64
ndarray.itemsize
數組中每個元素的字節大小。例如,float64類型的元素大小爲8(= 64/8),而complex32類型中的項目大小爲4(= 32/8)。相當於ndarray.dtype.itemsize。
ndarray.data
該緩衝區包含數組的實際元素。通常,我們不需要使用它,因爲我們將使用循秩訪問訪問數組中的元素。
例子:
>>> 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'>
三 數組的創建
下面我們就來介紹如何創建數組。
方法一:使用python 列表或者元組創建,array的dtype將會取決於您輸入元素的類型。如果您輸入的數字都爲int或者都爲float,那麼array的類型也將是這個。
>>> 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時請使用[],切勿省略。
>>> a = np.array(1,2,3,4) # WRONG
>>> a = np.array([1,2,3,4]) # RIGHT
可以將array轉換成二維數組,形似[array(),array(),array().........]。以同樣的方法可以創建三維,乃至更多維度的數組
>>> b = np.array([(1.5,2,3), (4,5,6)]) # 注意到這裏混用了int和float,最終全部轉換成了float
>>> 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]])
array的初始化:創建完成後數組內部元素是未知的,儘量應當初始化它。下面介紹幾個用於初始化的函數
1.zeros,創建一個一定大小的,內部元素全部填充爲0的數組
2.ones,創建一個一定大小的,內部元素全部填充爲1的數組
3.empty,創建一個一定大小的,內部元素全部爲隨機數的數組,默認類型爲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同樣提供了可以返回範圍的函數,
np.arange( lo, hi, delta ) # 從lo開始直到hi(不包括hi),每隔delta給一個數
>>> 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也提供了相似功能的函數,這個函數可以規定將lo到hi平分爲多少步走完。
>>> 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. ])
這一函數可以很簡便地用於繪函數圖,並規定精度,代碼如下:
>>> from numpy import pi
>>> x = np.linspace( 0, 2*pi, 100 ) # useful to evaluate function at lots of points
>>> f = np.sin(x)
四 數組的打印
如果您要打印多維數組,numpy將以如下規則進行:
1.從左到右打印最後一個維度的元素
2.從上到下打印倒數第二個軸的元素
3.剩下的維度一樣從上到下,只不過每一個矩陣都和下一個分開打印
總之,一維數組打印爲一行,二維數組打印爲一個矩陣,三維數組打印爲矩陣列表
>>> 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]]]
注意:如果數組過於巨大,比如上萬行,上萬列等等。numpy將自動打印邊角的元素
>>> print(np.arange(10000))
[ 0 1 2 ..., 9997 9998 9999]
>>>
>>> print(np.arange(10000).reshape(100,100))
[[ 0 1 2 ..., 97 98 99]
[ 100 101 102 ..., 197 198 199]
[ 200 201 202 ..., 297 298 299]
...,
[9700 9701 9702 ..., 9797 9798 9799]
[9800 9801 9802 ..., 9897 9898 9899]
[9900 9901 9902 ..., 9997 9998 9999]]
要禁止numpy這麼做,強制打印整個數組,可以輸入下列內容以禁止打印角點。
>>> np.set_printoptions(threshold='nan')
五 基礎操作
1.數組的運算。當進行數組的運算時,將會創建一個新的數組來保存運算結果。
相同大小的數組之間可以進行:
(1)加減操作,每個元素都被加減;
(2)平方(寫作**),sin()等函數操作,其中的每個元素都進行該運算,並填入結果中
(3)bool運算,每個元素都進行這樣的判斷,在結果中填入T/F
>>> 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], dtype=bool)
numpy中,*表示數組對應位置的元素相乘,矩陣乘法要使用.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.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 >>> 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'
對於那些創建新的數組來保存結果的運算,當兩種不同類型的元素運算時,結果自動變成兩種中更精確那種類型,比如float+complex->complex
>>> a = np.ones(3, dtype=np.int32) >>> b = np.linspace(0,pi,3) >>> b.dtype.name 'float64' >>> c = a+b >>> c array([ 1. , 2.57079633, 4.14159265]) >>> c.dtype.name 'float64' >>> d = np.exp(c*1j) >>> d array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j, -0.54030231-0.84147098j]) >>> d.dtype.name 'complex128'
numpy提供求所有元素的sum(),min(),max(),mean()等一元運算,這些都需要調用numpy,這些操作默認是對數組的一切元素進行,不論數組的形狀,維度
>>> 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
>>> a = np.array([[1, 2], [3, 4]]) >>> np.mean(a) 2.5
如果要對特定的維度上進行上述操作,請指定維度,即sum(axis= ),注意軸的序列是列axis=0,行axis=1。
>>> 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]])
>>> a = np.array([[1, 2], [3, 4]]) >>> np.mean(a) 2.5 >>> np.mean(a, axis=0) array([ 2., 3.]) >>> np.mean(a, axis=1) array([ 1.5, 3.5])
其他操作:numpy還支持sin cos exp sqrt等常規函數,這些函數對數組裏的所有元素進行操作
>>> 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的list相似
>>> 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多維數組的元素具有一個多維的索引,通過元組[a,b],(a行b列,ab均爲0-index)可以訪問之,切片也是一樣
>>> 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,:]
# 維度取值應當爲0-n的值,但是python允許超過這個範圍,並且取出mod n 的秩 ,-1表示最後一行 array([40, 41, 42, 43])
如果覺得太多的:,:,:麻煩,可以用...(三個點)代替,其中的維度將使用盡量多的:,代替。
比如B[1,...],則代表第一片矩陣的全部。
>>> 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]])
多維數組可以進行迭代,但是是對第一個維度進行
>>> 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
第一部分到此結束,如果覺得這一部分對您有幫助的話,請點贊。如果我的翻譯哪裏不妥,還請指出。
2018/3/23