天天看點

python資料分析 -- numpy庫初識

标簽(空格分隔): 王小草機器學習筆記

python的強大之處不但因為簡潔易學高效,還在于她有許多庫,可以友善我們得到想要的計算。比如今天講的numpy庫,為python提供了快速的多元數組的處理能力。有人數,numpy庫的出現使得python可以像matlab一樣去計算了。(matlab是10年前乃至今日仍然大受青睐的草稿本式的程式設計語言)。

1. 導入Numpy庫

要調用numpy庫,我們就要導入這個庫,導入的語句就一句。

as 後面是重命名,也可以說是縮寫,在我們的程式中,我們隻要寫np,自動就代碼numpy。這是約定俗稱的一個簡稱,當其他人閱讀你的代碼的時候,他們也知道np代表的就是Numpy,是以縮寫最好不要自己創新。

2. 使用Aarry建立數組

2.1 通過Array傳遞List

标準Python的清單(list)中,元素本質是對象。

如:L = [1, 2, 3],需要3個指針和三個整數對象,對于數值運算比較浪費記憶體和CPU。

是以,Numpy提供了ndarray(N-dimensional array object)對象:存儲單一資料類型的多元數組。

建立一維數組:

L = [, , , , , ]
print L
a = np.array(L)
print a
           

列印結果:

[1, 2, 3, 4, 5, 6]
[1 2 3 4 5 6]
           

建立多元數組:

嵌套多個list

b = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print b
           

列印結果:

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
           

2.2 數組大小

檢視數組大小

print a.shape
print b.shape
           

列印結果:

a是6行1列,b是3行4列

(6L,)
(3L, 4L)
           

強制修改數組大小

1.将3*4的數組改成4*3的數組

b.shape = 4, 3
print b
           

列印結果:

從(3,4)改為(4,3)并不是對數組進行轉置,而隻是改變每個軸的大小,數組元素在記憶體中的位置并沒有改變,還是按照1,2,3,4,5…12這樣的順序來排列的。

[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
           

2.當某個軸為-1時,将根據數組元素的個數自動計算此軸的長度

b.shape = 2, -1
print b
           

列印結果:

行是2行,列為-1的話就表示根據行來定,是以是6列

[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]]
           

修改數組大小後成新數組

使用reshape方法,可以建立改變了尺寸的新數組,原數組的shape保持不變

c = b.reshape((4, -1))
print c
           

建立的新數組,仍然與老數組共享記憶體,修改任意一個将影響另外一個。

比如修改b數組的第1行第2列的元素為20,再來看b和c兩個數組的變化

2.3 擷取數組的元素類型

檢視資料類型

print a.dtype
print b.dtype
           

建立指定元素類型的數組

可以通過dtype參數在建立時指定元素類型

d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.float)
f = np.array([[1+4j, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.complex)
print d
print f
           

列印結果:分别是浮點型與複數型

[[  1.   2.   3.   4.]
 [  5.   6.   7.   8.]
 [  9.  10.  11.  12.]]

[[  1.+4.j   2.+0.j   3.+0.j   4.+0.j]
 [  5.+0.j   6.+0.j   7.+0.j   8.+0.j]
 [  9.+0.j  10.+0.j  11.+0.j  12.+0.j]]
           

更改元素類型

如果更改元素類型,可以使用astype安全的轉換

f = d.astype(np.int)
print f
           

列印結果:

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
           

3. 使用函數建立

3.1 arrage

如果生成一定規則的資料,可以使用NumPy提供的專門函數

arange函數類似于python的range函數:指定起始值、終止值和步長來建立數組

和Python的range類似,arange同樣不包括終值;但arange可以生成浮點類型,而range隻能是整數類型

生成1開始,10結束(不包含10),步長為0.5的一個數組

a = np.arange(, , )
print a
           

列印結果:

[ 1.   1.5  2.   2.5  3.   3.5  4.   4.5  5.   5.5  6.   6.5  7.   7.5  8.
  8.5  9.   9.5]
           

3.2 linespace

linspace函數通過指定起始值、終止值和元素個數來建立數組,預設包括終止值

b = np.linspace(1, 10, 10)
print b
           

列印結果:生成了一個1到10,步長為1的等差數列,并且時前閉後閉的。

[  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.]
           

可以通過endpoint關鍵字指定是否包括終值 ,預設是包括的。

c = np.linspace(, , , endpoint=False)
print c
           

列印結果:生成了1到9的10個等差數列

[ 1.   1.9  2.8  3.7  4.6  5.5  6.4  7.3  8.2  9.1]
           

3.3 logspace

和linspace類似,logspace可以建立等比數列

下面函數建立起始值為10^1,終止值為10^2,有20個數的等比數列

d = np.logspace(, , , endpoint=False)
print d
           

列印結果:

[ 10.          11.22018454  12.58925412  14.12537545  15.84893192
  17.7827941   19.95262315  22.38721139  25.11886432  28.18382931
  31.6227766   35.48133892  39.81071706  44.66835922  50.11872336
  56.23413252  63.09573445  70.79457844  79.43282347  89.12509381]
           

下面建立起始值為2^0,終止值為2^10(不包括),有10個數的等比數列

f = np.logspace(, , , endpoint=True, base=)
print f
           

列印結果:

[           
            
         ]
           

3.4 frombuffer, fromstring, fromfile

使用 frombuffer, fromstring, fromfile等函數可以從位元組序列建立數組

s = 'ABCDZ'
g = np.fromstring(s, dtype=np.int8)
           

列印結果:

[65 66 67 68 90]
           

4. 存取

4.1 正常辦法

數組元素的存取方法和Python的标準方法相同

首先我們使用arange建立一個數組a

[0 1 2 3 4 5 6 7 8 9]
           

擷取某個元素

print a[]
           

擷取索引為3的元素

3
           

擷取一組元素,切片[3,6),左閉右開

print a[:]
           
[3 4 5]
           

省略開始下标,表示從0開始

print a[:]
           
[0 1 2 3 4]
           

下标為負表示從後向前數

print a[:]
           
[3 4 5 6 7 8 9]
           

取索引[1,8)步長為2

print a[::]
           
[1 3 5 7]
           

步長為-1,即翻轉

print a[::-]
           
[9 8 7 6 5 4 3 2 1 0]
           

切片資料是原數組的一個視圖,與原數組共享内容空間,可以直接修改元素

a[:] = , , 
print a
           
[ 0 10 20 30  4  5  6  7  8  9]
           

4.2 整數數組的存取

根據整數數組存取:當使用整數序列對數組元素進行存取時,

将使用整數序列中的每個元素作為下标,整數序列可以是清單(list)或者數組(ndarray)。

使用整數序列作為下标獲得的數組不和原始數組共享資料空間。

//建立兩個數組
a = np.logspace(, , , base=)
print a
i = np.arange(, , )
print i

//利用i取a中的元素
b = a[i]
print b
           

列印結果

[   1.    2.    4.    8.   16.   32.   64.  128.  256.  512.]

[0 2 4 6 8]

[   1.    4.   16.   64.  256.]
           
//b的元素更改,a中元素不受影響
b[] = 
print b
print a
           

列印結果:b變了,a不變

[   1.     4.     1.6   64.   256. ]
[   1.    2.    4.    8.   16.   32.   64.  128.  256.  512.]
           

4.3 布爾數組的存取

使用布爾數組i作為下标存取數組a中的元素:傳回數組a中所有在數組b中對應下标為True的元素

首先生成10個滿足[0,1)中均勻分布的随機數

a = np.random.rand()
print a
           
[ 0.84334711  0.54587789  0.41350371  0.73992619  0.00475762  0.0972838
  0.0522206   0.6696739   0.33550459  0.64959176]
           

大于0.5的元素索引

print a > 
           
[ True  True False  True False False False  True False  True]
           

大于0.5的元素,列印出了一組布爾類型的值,符合條件的為true

b = a[a > ]
print b
           
[ 0.84334711  0.54587789  0.73992619  0.6696739   0.64959176]
           

将原數組中大于0.5的元素截取成0.5

a[a > ] = 
print a

//b不受影響
print b
           
[ 0.5         0.5         0.41350371  0.5         0.00475762  0.0972838
  0.0522206   0.5         0.33550459  0.5       ]
[ 0.84334711  0.54587789  0.73992619  0.6696739   0.64959176]
           

4.4 二維數組的切片

生成二維數組

若我們想生成以下這樣一個多元數組:

[[ 0 1 2 3 4 5]

[10 11 12 13 14 15]

[20 21 22 23 24 25]

[30 31 32 33 34 35]

[40 41 42 43 44 45]

[50 51 52 53 54 55]]

可以經過以下幾步

先生成行向量,0到60,步長為10的數組。

[ 0 10 20 30 40 50]
           

将行向量,轉化成列向量

[[ 0]
 [10]
 [20]
 [30]
 [40]
 [50]]
           

生成一個0到5,步長為1的行向量

[0 1 2 3 4 5]
           

将列向量b每一列都c行向量

f = b + c
print f
           
[[ 0  1  2  3  4  5]
 [10 11 12 13 14 15]
 [20 21 22 23 24 25]
 [30 31 32 33 34 35]
 [40 41 42 43 44 45]
           

将上面所有步驟合起來可以用一句代碼表示:

a = np.arange(, , ).reshape((-, )) + np.arange()
           

二維數組的切片

//大括号裡,前面的list表示行的索引,後面的list表示列的索引
//比如第一個數提取的是行索引為0列索引為2
print a[(,,,), (,,,)]

//擷取行号從3開始(包括3),列号是0,2,5的元素
print a[:, [, , ]]

//建立布爾類型的數組
i = np.array([True, False, True, False, False, True])
//擷取為true的行
print a[i]
//擷取為true的行的列索引為3的元素
print a[i, ]
           

列印結果:

[ 2 13 24 35]

[[30 32 35]
 [40 42 45]
 [50 52 55]]

[[ 0  1  2  3  4  5]
 [20 21 22 23 24 25]
 [50 51 52 53 54 55]]

[ 3 23 53]
           

5. 繪圖

5.1 繪制正态分布機率密度函數

mu =   //均值
sigma =   //标準差

//建立一個50個元素的數組,收尾與均值相差三個标準差
x = np.linspace(mu -  * sigma, mu +  * sigma, ) 

//根據正太分布的公式寫出y
y = np.exp(-(x - mu) **  / ( * sigma ** )) / (math.sqrt( * math.pi) * sigma)

//以x,y為橫縱坐标,'r-'表示紅色線,'ro-表示紅色線加原點',linewidth為線的粗細度
#plot.plot(x, y, 'ro-', linewidth=2)

//或者也可以:用'go'表示綠色原點,markersize為原點大小
plot.plot(x, y, 'r-', x, y, 'go', linewidth=, markersize=)

//有灰色格子
plot.grid(True)

//畫出來吧,少年!
plot.show()
           

圖形如下:

python資料分析 -- numpy庫初識

接下去,我們再來看幾個好玩的畫圖案例

5.2 損失函數:Logistic損失(-1,1)/SVM Hinge損失/ 0/1損失

x = np.linspace(-, , )
y_logit = np.log( + np.exp(-x)) / math.log()
y_01 = x < 
y_hinge =  - x
y_hinge[y_hinge < ] = 
//label表示标記
plot.plot(x, y_logit, 'r-', label='Logistic Loss', linewidth=)
plot.plot(x, y_01, 'g-', label='0/1 Loss', linewidth=)
plot.plot(x, y_hinge, 'b-', label='Hinge Loss', linewidth=)
plot.grid()
//标記的放的位置,這裡是右上角
plot.legend(loc='upper right')
plot.show()
           

圖形畫出來如下:

python資料分析 -- numpy庫初識

5.3 x^x

x = np.linspace(-1.3, 1.3, 101)
y = f(x)
plot.plot(x, y, 'g-', label='x^x', linewidth=2)
plot.grid()
plot.legend(loc='upper right')
plot.show()
           
python資料分析 -- numpy庫初識

5.4 胸型線

(前方高能。。。)

x = np.arange(, , -)
y = (- * x * np.log(x) + np.exp(-( * (x -  / np.e)) ** ) / ) / 
//設定畫布大小
plot.figure(figsize=(,))
plot.plot(y, x, 'r-', linewidth=)
plot.grid(True)
plot.show()
           

這個圖太辣眼睛了。。。男生心裡估計已經浮現過ABCDEF了。。

python資料分析 -- numpy庫初識

5.5 心形線

t = np.linspace(, , )
x =  * np.sin(t) ** 
y =  * np.cos(t) -  * np.cos(*t) -  * np.cos(*t) - np.cos(*t)
plot.plot(x, y, 'r-', linewidth=)
plot.grid(True)
plot.show()
           

嗯,這個圖美,願大家有情人終成眷屬

python資料分析 -- numpy庫初識

5.6 漸開線

t = np.linspace(, , num=)
x = t*np.sin(t) + np.cos(t)
y = np.sin(t) - t*np.cos(t)
plot.plot(x, y, 'r-', linewidth=)
plot.grid()
plot.show()
           
python資料分析 -- numpy庫初識

關于畫函數圖,總結規律,其實就是,設定一個x的變量,然後根據某種公式用x得到y的分布,然後把x,y用Plot函數套進去,什麼顔色啊,圓點啊,線條粗細啊之類的都可以套模闆寫。棒棒棒!

繼續閱讀