1. 程式人生 > >學機器學習,不會資料分析怎麼行?之NumPy詳解

學機器學習,不會資料分析怎麼行?之NumPy詳解

你可以通過ndarray的astype方法明確地將一個數組從一個dtype轉換成另一個dtype:

NumPy計算

  這裡將介紹Numpy的一些基本計算

1.條件運算

  

2.統計運算

  求最大值

  

  求最小值

  

  平均值

  方差

3.線性代數

    轉置是重塑的一種特殊形式,它返回的是源資料的檢視(不會進行任何複製操作)。陣列不僅有transpose方法,還有一個特殊的T屬性

在進行矩陣計算時,經常需要用到該操作,比如利用np.dot計算矩陣內積

對於高維陣列,我們可以使用transpose進行轉置操作(有點難懂)

在這裡,如果我們使用arr.shape(),則會返回(2,2,4),第一個2表示兩組,第二個則表示每組都有兩行,4則表示4列。而這三個數字由一個元組(0,1,2)進行索引,所以使用arr.transpose((1, 0, 2))時,則表示將第一位數與第二位數交換位置。最終會得到圖中所示結果。

 當然,我們也可以使用.T進行操作,不過.T進行的只是軸對換而已。

 ndarray還有一個swapaxes方法,它需要接受一對軸編號

矩陣拼接

  • 水平拼接

  

  • 垂直拼接

基本索引和切片

1.一維陣列

  NumPy陣列的索引是一個內容豐富的主題,因為選取資料子集或單個元素的方式有很多。一維陣列很簡單。從表面上看,它們跟Python列表的功能差不多

  如上所示,當你將一個標量值賦值給一個切片時(如arr[5:8]=12),該值會自動傳播到整個選區。跟列表最重要的區別在於,陣列切片是原始陣列的檢視。這意味著資料不會被複制,檢視上的任何修改都會直接反映到源陣列上。

  先建立一個arr的切片

  修改其中的值,會發現陣列arr中的值也會改變

  切片[ : ]會給陣列中所有的值賦值

2.高維陣列

  對於高維度陣列,能做的事情更多。在一個二維陣列中,各索引位置上的元素不再是標量而是一維陣列

  索引方式

  在多維陣列中,如果省略了後面的索引,則返回物件會是一個維度低一點的ndarray(它含有高一級維度上的所有資料),且標量值和陣列都可用於賦值。

切片索引

  ndarray的切片語法跟Python列表這樣的一維物件差不多。對於之前的二維陣列arr2d,其切片方式稍顯不同

  可以看出,它是沿著第0軸(即第一個軸)切片的。也就是說,切片是沿著一個軸向選取元素的。表示式arr2d[:2]可以被認為是“選取arr2d的前兩行”。

  當然,也可以一次傳入多個切片,像傳入多個索引那樣

 像這樣進行切片時,只能得到相同維數的陣列檢視。通過將整數索引和切片混合,可以得到低維度的切片。

 

布林型索引

  來看這樣一個例子,假設我們有一個用於儲存資料的陣列以及一個儲存姓名的陣列(含有重複項)。在這裡,我將使用numpy.random中的randn函式(上面表格中漏了這個)生成一些正態分佈的隨機資料:

  假設每個名字都對應data陣列中的一行,而我們想要選出對應於名字"Bob"的所有行。跟算術運算一樣,陣列的比較運算(如==)也是向量化的。因此,對names和字串"Bob"的比較運算將會產生一個布林型陣列,這個布林型陣列課用於陣列索引

注:布林型陣列的長度必須跟被索引的軸長度一致,如果布林型陣列的長度不對,布林型選擇就會出錯。

  此外,我們還可以將布林型陣列跟切片、整數(或整數序列)混合使用

 

  如果我們要選取多個名字,則組合應用多個布林條件,使用 &、| 之類的布林算術運算子即可

 

 注:通過布林型索引選取陣列中的資料,將總是建立資料的副本,即使返回一模一樣的陣列也是如此。

 花式索引

花式索引(Fancy indexing)是一個NumPy術語,它指的是利用整數陣列進行索引。假設我們有一個8×4陣列

array([[ 0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.],
       [ 4.,  4.,  4.,  4.],
       [ 5.,  5.,  5.,  5.],
       [ 6.,  6.,  6.,  6.],
       [ 7.,  7.,  7.,  7.]])

為了以特定順序選取行子集,只需傳入一個用於指定順序的整數列表或ndarray即可

使用負數索引將會從末尾開始選取行

一次傳入多個索引陣列會返回一個一維陣列,其中的元素對應各個索引元組

注:花式索引跟切片不一樣,它總是將資料複製到新陣列中。

隨機數 

1.偽隨機數生成

  NumPy可生成隨機數,這些隨機數是通過演算法基於隨機數生成器種子,在確定性條件下生成的,是偽隨機數。我們可以使用normal來得到標準正態分佈的樣本陣列,並且,在需要產生大量隨機數時,NumPy的隨機數生成速度比Python內建的random快了不止一個數量級

同時,我們可以用NumPy的np.random.seed更改隨機數生成種子

np.random.seed(1234)

numpy.random的資料生成函式使用了全域性的隨機種子。要避免全域性狀態,我們可以使用numpy.random.RandomState,建立一個與其它隔離的隨機數生成器

rng = np.random.RandomState(1234)
rng.randn(10)

Out: 
array([ 0.4714, -1.191 ,  1.4327, -0.3127, -0.7206,  0.8872,  0.8596,
       -0.6365,  0.0157, -2.2427])

下圖給出了numpy.random中的部分函式

下面屬於補充了

2.例項:隨機漫步

我們可以通過模擬隨機漫步來說明如何運用陣列運算。先來看一個簡單的隨機漫步的例子:從0開始,步長1和-1出現的概率相等。

這提示就是隨機漫步中各步的累計和,可以用一個數組運算來實現。因此,我用np.random模組一次性隨機產生1000個“擲硬幣”結果(即兩個數中任選一個),將其分別設為1或-1,然後計算累計和

有了這些資料之後,我們就可以沿著漫步路徑做一些統計工作了,比如求取最大值和最小值等

1 walk.min()
2 
3 walk.max()

再看一個複雜點的統計任務——首次穿越時間,即隨機漫步過程中第一次到達某個特定值的時間。假設我們想要知道本次隨機漫步需要多久才能距離初始0點至少10步遠(任一方向均可)。np.abs(walk)>=10可以得到一個布林型陣列,它表示的是距離是否達到或超過10,而我們想要知道的是第一個10或-10的索引。可以用argmax來解決這個問題,它返回的是該布林型陣列第一個最大值的索引(True就是最大值):

In [103]:
(np.abs(walk) >= 10).argmax()

Out[103]:
57

一次模擬多個隨機漫步

如果你希望模擬多個隨機漫步過程(比如5000個),只需對上面的程式碼做一點點修改即可生成所有的隨機漫步過程。只要給numpy.random的函式傳入一個二元元組就可以產生一個二維陣列,然後我們就可以一次性計算5000個隨機漫步過程的累計和了:

In [105]:
nwalks = 5000
nsteps = 1000
draws = np.random.randint(0, 2, size=(nwalks, nsteps))
steps = np.where(draws > 0, 1 , -1)
walks = steps.cumsum(1)
walks

Out[105]:
array([[-1,  0, -1, ..., 12, 11, 10],
       [ 1,  2,  3, ..., -2, -1,  0],
       [-1,  0,  1, ..., 34, 35, 36],
       ...,
       [ 1,  0, -1, ..., 32, 33, 32],
       [ 1,  0,  1, ..., 20, 21, 22],
       [-1,  0, -1, ..., 18, 19, 18]], dtype=int32)

剩下的資料處理就由你們自行發揮了。

結尾

上面只介紹了NumPy的部分內容,剩下的如歸一化操作,排序,檔案輸入輸出(大部分人都用pandas載入文字或表格資料)等等都沒寫入,但都在程式碼中給出了示例。頭一回部落格寫這麼長(雖說圖片居多),中間還幾次頁面錯誤沒儲存。。。如有錯誤,歡迎大家指正。

參考部落格:

參考書籍:

《利用Python進行資料分析·第2版》