Numpy數組使你能夠將許多種數據處理任務表述爲簡潔的數組表達式。利用數組表達式代替循環的作法,一般被稱爲矢量化。通常來講,矢量化數組運算要比等價的純Python方式快上一兩個數量級(甚至更多)尤爲是各類數值計算。數組
假如咱們想要在一組值上計算函數sqrt(x^2+y^2)。np.meshgrid函數接受兩個一維數組,併產生兩個二維矩陣:app
In [4]: points=np.arange(-5,5,0.01) In [5]: xs,ys=np.meshgrid(points,points) #產生1000個間隔相等的點 In [6]: ys Out[6]: array([[-5. , -5. , -5. , ..., -5. , -5. , -5. ], [-4.99, -4.99, -4.99, ..., -4.99, -4.99, -4.99], [-4.98, -4.98, -4.98, ..., -4.98, -4.98, -4.98], ..., [ 4.97, 4.97, 4.97, ..., 4.97, 4.97, 4.97], [ 4.98, 4.98, 4.98, ..., 4.98, 4.98, 4.98], [ 4.99, 4.99, 4.99, ..., 4.99, 4.99, 4.99]])
如今,對該函數的求值運算就好辦了,把兩個數組當作浮點數那樣編寫表達式便可:dom
In [8]: import matplotlib.pyplot as plt In [9]: z=np.sqrt(xs ** 2 + ys ** 2) In [10]: z Out[10]: array([[7.07106781, 7.06400028, 7.05693985, ..., 7.04988652, 7.05693985, 7.06400028], [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815, 7.05692568], [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354, 7.04985815], ..., [7.04988652, 7.04279774, 7.03571603, ..., 7.0286414 , 7.03571603, 7.04279774], [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354, 7.04985815], [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
效果以下:ide
函數值得圖形結果如上所示,使用的是matlpltlib的imshow函數建立的,colorbar顯示右側的條形欄,title顯示標題。函數
numpy.where函數是三元表達式x if condition else y的矢量化版本。假設咱們有一個布爾數組和兩個值數組:測試
In [24]: xarr=np.array([1.1,1.2,1.3,1.4,1.5,]) In [25]: yarr=np.array([2.1,2.2,2.3,2.4,2.5]) In [26]: cond=np.array([True,False,True,True,False])
假設咱們想要根據cond的值選取xarr和yarr的值:當cond種的值爲True時,選取xarr的值,不然選取yarr值。那麼:spa
In [27]: result=[(x if c else y) ...: for x,y,c in zip(xarr,yarr,cond)] ...: In [28]: result Out[28]: [1.1, 2.2, 1.3, 1.4, 2.5]
這有幾個問題。第一,它對大多數數組的處理速度不是很快(由於全部操做都是純Python完成的)。第二,沒法用於多維數組。若使用np.where,則該功能寫的很是簡潔:code
In [30]: result=np.where(cond,xarr,yarr) In [31]: result Out[31]: array([1.1, 2.2, 1.3, 1.4, 2.5])
np.where的第二個和第三個參數沒必要是數組,它們均可以是標量值。在數據分析工做中,where一般用於根據另外一個數組而產生一個新數組。假設有一個隨機數數據組成的矩陣,你但願將全部正值替換成2,將全部負值替換成-2,。若利用np.where,則會很是簡單:blog
In [32]: arr=randn(4,4) In [33]: arr Out[33]: array([[-0.86420168, 0.46737262, 1.52870151, 0.87138646], [ 1.25042219, -1.26081875, 1.13138761, 0.30288777], [-0.17935329, 0.6377377 , 2.94953378, -1.16395691], [ 0.71109135, -0.88708025, 2.25487302, 0.67770479]]) In [34]: np.where(arr>0,2,-2) Out[34]: array([[-2, 2, 2, 2], [ 2, -2, 2, 2], [-2, 2, 2, -2], [ 2, -2, 2, 2]])
In [36]: np.where(arr>0,2,arr) #只將正值設置爲2
Out[36]:
array([[-0.86420168, 2. , 2. , 2. ],
[ 2. , -1.26081875, 2. , 2. ],
[-0.17935329, 2. , 2. , -1.16395691],
[ 2. , -0.88708025, 2. , 2. ]])
傳遞給where的數組大小能夠不相等,甚至能夠是標量值。索引
假如咱們有兩個布爾型數組cond1和cond2。但願根據4種不一樣的布爾值組合實現不一樣的賦值操做:
result=[] for i in range(n): ...: if cond1[i] and cond2[i]: ...: result.append(0) ...: elif cond[1]: ...: result.append(1) ...: elif cond2[i]: ...: result.append(2) ...: else: ...: result.append(3)
這個for循環能夠改寫成一個嵌套的where表達式:
np.where(cond1 & cond2,0,np.where(cond1,1,np.where(cond2,2,3)))
在這個特殊的例子裏,咱們還能夠利用「布爾值在計算過程當中能夠被當作0或1處理」這個事實,因此還能將其寫成這樣的算術運算:
result= 1 * (cond1-cond2) +2 * (cond2 & -cond1) + 3 * -(cond1 | cond2)
In [40]: cond1=True In [41]: cond2=False In [42]: result= 1 * (cond1-cond2) +2 * (cond2 & -cond1) + 3 * -(cond1 | cond2) In [43]: result Out[43]: -2
能夠經過數組上一組數學函數對整個數組或某個軸向的數據進行統計運算。sum、mean以及標準差std等聚合運算。既能夠當作數組的實例方法調用,也能夠當作頂級numpy函數使用:
In [44]: arr=np.random.randn(5,4) #正態分佈 In [45]: arr Out[45]: array([[-0.66406273, 0.8416933 , 0.50576114, 0.94731857], [ 1.02715787, -0.90753908, -0.98615632, 0.41013117], [ 0.77767026, 0.93195883, -0.43795365, -0.07269931], [-0.06836068, -0.36374319, 1.03753398, -0.47534392], [-2.86457512, 0.03055321, 0.20997436, 0.4156038 ]]) In [46]: np.mean(arr) Out[46]: 0.014746125565483863 In [47]: arr.sum() Out[47]: 0.2949225113096773
mean和sum這類的函數,能夠接受一個axis參數(用戶計算該軸向上的統計值),最終結果是一個少一維的數組:
In [48]: arr.mean() Out[48]: 0.014746125565483863 In [49]: arr.mean(axis=1) Out[49]: array([ 0.40767757, -0.11410159, 0.29974403, 0.03252155, -0.55211094])
其餘如cumsum和cumprod之類的方法則不聚合,而是產生一個由中間結果組成的數組:
In [50]: arr=np.array([[0,1,2],[3,4,5],[6,7,8]]) In [51]: arr.cumsum(0) Out[51]: array([[ 0, 1, 2], [ 3, 5, 7], [ 9, 12, 15]], dtype=int32) In [52]: arr.cumprod(1) Out[52]: array([[ 0, 0, 0], [ 3, 12, 60], [ 6, 42, 336]], dtype=int32)
cumsum:全部元素的累積和,裏面能夠不帶參數,若是帶參數只能是0或1
In [60]: arr
Out[60]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [57]: arr.cumsum() Out[57]: array([ 0, 1, 3, 6, 10, 15, 21, 28, 36], dtype=int32) In [58]: arr.cumsum(0) Out[58]: array([[ 0, 1, 2], [ 3, 5, 7], [ 9, 12, 15]], dtype=int32) In [59]: arr.cumsum(1) Out[59]: array([[ 0, 1, 3], [ 3, 7, 12], [ 6, 13, 21]], dtype=int32)
從上能夠看出,若是不帶參數,結果爲一個少一維的數組,值爲前面元素累積和;若是帶參數爲0,表述縱向累積和,若是帶參數爲1,則爲橫向累積和(等同於axis=1)
cumprod相似,不過它是計算累積積
基本數組統計方法:
sum: 對數組中所有或某軸向的元素求和。零長度的數組sum爲0
mean:算術平均差。零長度的數組mean爲NaN。
std、var:分別爲標準差和方差,自由度可調(默認爲n)
min、max:最小值和最大值
argmin、argmax:分別爲最小和最大元素的索引
cumsum、cumprod:全部元素的累積和、累積積
從上面咱們知道,布爾值會被強制轉換成1(True)和0(False)。所以,sum常常用來對布爾型數組中的True值計數:
In [64]: arr=randn(100) In [65]: (arr>0).sum() Out[65]: 45
另外還有2個方法any和all,它們對布爾型數組很是有用。any用於測試數組中是否存在一個或多個True,而all則檢查數組中全部值是否都是True:
In [67]: bools=np.array([False,False,True,False]) In [68]: bools.any() Out[68]: True In [69]: bools.all() Out[69]: False