半小時學完Numpy
阿新 • • 發佈:2019-01-13
前面寫了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]])