1. 程式人生 > >半小時學完Numpy

半小時學完Numpy

前面寫了Matplotlib,這裡繼續把科學計算基礎庫Numpy給寫完,後面再寫個Pandas那麼三大件就寫完了,然後準備入手ML。由於是程式碼+輸出的形式,所以半小時學完是沒問題的。

一個在Python中做科學計算的基礎庫,重在數值計算,也是大部分PYTHON科學計算庫的基礎庫,多用於在大型、多維陣列上執行數值運算。注意:是數值型別計算

第一部分:建立陣列以及型別

import numpy as np
import random
#建立np陣列的三種方式
t1 = np.array([1,2,3,4,5])
t2 = np.array(range(6))
t3 = np.arange(2,10,2)  #推薦這一種,方式和range()方法一樣
print(t1,t2,t3)

#元素型別   t型別為ndarray  元素還有型別
print(type(t1))  
print(t1.dtype)

#建立bool型別  非0即True
t4 = np.array([1,0,2,1],dtype=bool)
print(t4)

#調整資料型別
t5 = t4.astype("int8")
print(t5.dtype)

#np中的小數
t6 = np.array([random.random() for i in range(10)])
t7 = np.round(t6,2) #取兩位
print(t6)
print(t7)


第二部分:二維陣列以及numpy的計算

import numpy as np

#陣列的形狀 
#生成二維陣列
t1 = np.arange(24).reshape(4,6) #一維變二維
print(t1)
print(t1.shape) # 陣列的形狀
#陣列的計算  +2那麼是每個元素都+2   這叫做廣播機制
print(t1+2)
print(t1*2)
#print(t1/0) #注意這裡,非0數/0得到的是無窮inf

#矩陣之間運算,維度相同對應位置+-*/
t2 = np.arange(100,124).reshape(4,6)
print(t2)
print(t1*t2)  
print(t1+t2)

#再將二維轉一維
t3 = t1.reshape(1,24) #這種方法得到的還是[[]]
print(t3)
t4 = t1.flatten() #建議這種,得到的是[]  真正的一維
print(t4)

#print(t3*np.arange(24).reshape(4,6))  不同維度不能運算  其實同樣的行或者列是可以的,用到了再說

第三部分:讀取檔案

import numpy as np
#使用numpy讀取資料  CSV:Comma-Separated Value,逗號分隔值檔案

uk_file_path = "路徑.csv"
us_file_path = r"路徑.csv" #表示不對符合進行轉義 否則出現解碼錯誤

t1 = np.loadtxt(uk_file_path,delimiter=",",dtype=int)#,號分隔字串,資料以int型別讀入
t2 = np.loadtxt(us_file_path,delimiter=",",dtype=int,unpack=True) #unpack=True可以理解為轉置,還有其他屬性

#矩陣轉置  下面介紹了兩種方法
t = np.arange(24).reshape(4,6)
print(t.T)  #推薦這個,跟線代書上那樣直接寫的感覺
print(t.transpose())

第四部分:索引和切片

In [11]: t1 = np.arange(40).reshape(10,4)

In [12]: t1
Out[12]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23],
       [24, 25, 26, 27],
       [28, 29, 30, 31],
       [32, 33, 34, 35],
       [36, 37, 38, 39]])

In [13]: t1[2]   #取一行
Out[13]: array([ 8,  9, 10, 11])

In [14]: t1[3:]  #取連續的多行
Out[14]:
array([[12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23],
       [24, 25, 26, 27],
       [28, 29, 30, 31],
       [32, 33, 34, 35],
       [36, 37, 38, 39]])

In [16]: t1[[1,3,9]] #取不連續的多行
Out[16]:
array([[ 4,  5,  6,  7],
       [12, 13, 14, 15],
       [36, 37, 38, 39]])
#取列 通用的[,]    ,前放行後面放列
In [19]: t1[1,:]
Out[19]: array([4, 5, 6, 7])

In [20]: t1[1:3,:]
Out[20]:
array([[ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
 In [22]: t1[:,1]
Out[22]: array([ 1,  5,  9, 13, 17, 21, 25, 29, 33, 37])

In [23]: t1[[1,3,5],[0,1,2]] #取多個元素
Out[23]: array([ 4, 13, 22])

In [25]: t1[1,2]  #取一個元素
Out[25]: 6

In [26]: t1[2:,0:2] #取多行多列
Out[26]:
array([[ 8,  9],
       [12, 13],
       [16, 17],
       [20, 21],
       [24, 25],
       [28, 29],
       [32, 33],
       [36, 37]])
In [28]: t1[:,2]  #取第三列   不寫了,反正就是跟列表的切片差不多
Out[28]: array([ 2,  6, 10, 14, 18, 22, 26, 30, 34, 38])

第五部分:布林型別、三元運算子以及裁剪

In [34]: t = np.arange(24).reshape(4,6)

In [35]: t
Out[35]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])

In [36]: t < 10  #布林操作得到的還是矩陣
Out[36]:
array([[ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True, False, False],
       [False, False, False, False, False, False],
       [False, False, False, False, False, False]], dtype=bool)

In [37]: t[t<10] = 5  #<10的位置元素修改為5

In [38]: t
Out[38]:
array([[ 5,  5,  5,  5,  5,  5],
       [ 5,  5,  5,  5, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])

In [39]: t = np.arange(24).reshape(4,6)

In [40]: t2 = np.where(t<10,3,15) #三元運算子 <10修改為3,否則修改為15

In [41]: t2
Out[41]:
array([[ 3,  3,  3,  3,  3,  3],
       [ 3,  3,  3,  3, 15, 15],
       [15, 15, 15, 15, 15, 15],
       [15, 15, 15, 15, 15, 15]])
 In [45]: t = np.arange(24).reshape(4,6)
 In [48]: t = t.clip(8,10)   #裁剪,小於8的替換為8,大於的修改為10

In [49]: t
Out[49]:
array([[ 8,  8,  8,  8,  8,  8],
       [ 8,  8,  8,  9, 10, 10],
       [10, 10, 10, 10, 10, 10],
       [10, 10, 10, 10, 10, 10]]) 

第六部分:關於nan(not a number,讀取到的缺失資料經常就成了nan),常見統計函式

In [51]: a = np.nan #建立ann

In [52]: b = np.nan

In [53]: a
Out[53]: nan

In [54]: a == b  #發現兩個nan是不相等的,這一點很重要
Out[54]: False

In [55]: t = np.arange(24).reshape(4,6)

In [56]: t
Out[56]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])

In [57]: t = t.astype(float)  #因為nan是float型別,所以我們轉換下型別
In [65]: t[:,0] = 0

In [66]: t
Out[66]:
array([[  0.,   1.,   2.,   3.,   4.,   5.],
       [  0.,   7.,   8.,   9.,  10.,  11.],
       [  0.,  13.,  14.,  15.,  16.,  17.],
       [  0.,  19.,  20.,  nan,  22.,  23.]])

In [67]: np.count_nonzero(t) #統計0的個數
Out[67]: 20
In [70]: t==t
Out[70]:
array([[ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True],
       [ True,  True,  True, False,  True,  True]], dtype=bool)

In [71]: np.sum(t) #nan和任何數計算都是nan
Out[71]: nan
In [72]: np.isnan(t)
Out[72]:
array([[False, False, False, False, False, False],
       [False, False, False, False, False, False],
       [False, False, False, False, False, False],
       [False, False, False,  True, False, False]], dtype=bool)

In [73]: np.count_nonzero(np.isnan(t))  #通過這種方法來得到nan的個數
Out[73]: 1


In [74]: t = np.arange(12).reshape(3,4)

In [75]: t
Out[75]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

In [76]: t.sum(axis=0) #0軸上數字之和
Out[76]: array([12, 15, 18, 21])

In [77]: t.sum(axis=1) #1軸上數字之和
Out[77]: array([ 6, 22, 38])

In [78]: t.sum() #矩陣各個元素累加和
Out[78]: 66

In [80]: t=t.astype(float)

In [81]: t
Out[81]:
array([[  0.,   1.,   2.,   3.],
       [  4.,   5.,   6.,   7.],
       [  8.,   9.,  10.,  11.]])

In [82]: t[1,1]=np.nan

In [83]: t
Out[83]:
array([[  0.,   1.,   2.,   3.],
       [  4.,  nan,   6.,   7.],
       [  8.,   9.,  10.,  11.]])

In [84]: np.isnan(t)
Out[84]:
array([[False, False, False, False],
       [False,  True, False, False],
       [False, False, False, False]], dtype=bool)

In [85]: t[np.isnan(t)] = 1000  #修改nan位置的值

In [86]: t
Out[86]:
array([[    0.,     1.,     2.,     3.],
       [    4.,  1000.,     6.,     7.],
       [    8.,     9.,    10.,    11.]])
In [88]: t
Out[88]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

In [89]: t.mean()
Out[89]: 5.5

In [90]: t.mean(axis=0)
Out[90]: array([ 4.,  5.,  6.,  7.])

In [91]: np.median(t,axis=0)
Out[91]: array([ 4.,  5.,  6.,  7.])

In [92]: np.max(t,axis=0)
Out[92]: array([ 8,  9, 10, 11])

In [93]: np.min(t,axis=1)
Out[93]: array([0, 4, 8])

小練習:t中存在nan值,如何操作把其中的nan填充為每一列的均值

import numpy as np



def fill_ndarray(t1):
    for i in range(t1.shape[1]) : #遍歷每一列
        temp_col = t1[:,i] #當前的一列
        nan_num = np.count_nonzero(temp_col != temp_col)
        if nan_num != 0: #不為0,說明當前這一列有nan
            #當前一列不為nan的array
            temp_not_nan_col = temp_col[temp_col == temp_col]
            #選中當前為nan的位置,把值賦值不為nna的均值
            print("當前位置",temp_col[np.isnan(temp_col)])
            temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean()

    return t1

if __name__ == '__main__':
    t1 = np.arange(12).reshape(3,4).astype("float")
    t1[1,2:] = np.nan
    print(t1)
    t1 = fill_ndarray(t1)
    print(t1)

第七部分:陣列的拼接,交換陣列的行列

In [97]: t = np.arange(12).reshape(2,6)

In [98]: t
Out[98]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])

In [108]: t2=np.arange(12).reshape(2,6)

In [109]: np.vstack((t,t2))   #水平拼接
Out[109]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])

In [110]: np.hstack((t,t2))  #豎直拼接  注意:不管水平還是豎直,對應的維度要一致
Out[110]:
array([[ 0,  1,  2,  3,  4,  5,  0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11,  6,  7,  8,  9, 10, 11]])

In [112]: t = np.arange(12).reshape(3,4)

In [113]: t
Out[113]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

In [114]: t[[1,2],:]= t[[2,1],:]     #交換兩行

In [115]: t
Out[115]:
array([[ 0,  1,  2,  3],
       [ 8,  9, 10, 11],
       [ 4,  5,  6,  7]])

In [116]: t[:,[1,2]] = t[:,[2,1]] #交換兩列

In [117]: t
Out[117]:
array([[ 0,  2,  1,  3],
       [ 8, 10,  9, 11],
       [ 4,  6,  5,  7]])
 

第八部分:Numpy的一些補充

In [119]: t
Out[119]:
array([[ 0,  2,  1,  3],
       [ 8, 10,  9, 11],
       [ 4,  6,  5,  7]])

In [120]: np.argmax(t,axis=0) #在0軸上(也就是4列中)每列最大元素的位置
Out[120]: array([1, 1, 1, 1], dtype=int32)

In [121]: np.argmax(t)  #會當一個一維來計算位置所以索引是7
Out[121]: 7

In [122]: np.argmax(t,axis=1)  #在1軸上(也就是3行)每行最大元素的位置
Out[122]: array([3, 3, 3], dtype=int32)

In [123]: np.argmin(t,axis=1)
Out[123]: array([0, 0, 0], dtype=int32)

In [126]: np.zeros((3,4))  #生成指定行列的元素全為0的矩陣
Out[126]:
array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])
In [128]: np.ones((3,4))  #全為1的矩陣
Out[128]:
array([[ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.]])

In [129]: np.eye(4)  #對角線為1的方陣
Out[129]:
array([[ 1.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  1.]])

In [133]: np.random.rand(10)  #均勻分佈
Out[133]:
array([ 0.16913174,  0.62544667,  0.43679361,  0.47662989,  0.3806515 ,
        0.97137349,  0.32286633,  0.39535455,  0.5527933 ,  0.93698439])

In [134]: np.random.randn(10)  #正態分佈
Out[134]:
array([ 0.37551376, -0.71511313, -0.18858819,  1.23133696,  0.64860447,
        0.03031483,  0.0652931 , -0.01387029, -0.75130255, -0.30829577])

In [135]: np.random.randint(0,10)  #生成0-10中的隨機數  不包含10
Out[135]: 6
In [159]: np.random.randint(0,10,(3,4))   #生成隨機矩陣
Out[159]:
array([[0, 1, 8, 9],
       [0, 8, 6, 4],
       [3, 0, 4, 6]])

在這裡插入圖片描述