目錄
3.numpy的矩陣運算 - universal function
一、環境搭建
1.Anaconda簡介及安裝
Anaconda(官方下載地址)就是可以便捷獲取包且對包能夠進行管理,同時對環境可以統一管理的發行版本。Anaconda包含了conda、Python在內的超過180個科學包及其依賴項。
Anaconda可以看作一個集成了大量進行數據分析、機器學習所需要的python包的開發環境。使用Anaconda進行開發,開發者不必陷於依賴包的安裝、環境管理等瑣碎的操作中,因爲Anaconda提供了conda這一比pip更強大的包和環境管理器。
如果你需要的包要求不同版本的Python,你無需切換到不同的環境,因爲conda同樣是一個環境管理器。僅需要幾條命令,你可以創建一個完全獨立的環境來運行不同的Python版本,同時繼續在你常規的環境中使用你常用的Python版本。
具體安裝教程請看:https://blog.csdn.net/ITLearnHall/article/details/81708148。安裝非常簡單。
Anaconda更換國內下載源:https://blog.csdn.net/dream_allday/article/details/80344511
2.使用jupyter notebook
Jupyter Notebook是基於網頁的用於交互計算的應用程序。其可被應用於全過程計算:開發、文檔編寫、運行代碼和展示結果。
Jupyter Notebook實時展示代碼效果與matplotlib可視化庫結合簡直不要太爽。而且Jupyter Notebook可以進行markdown編輯,對知識點的理解再也不用寫成註釋了,學習必備利器!
安裝完Anaconda之後,在命令行中輸入jupyter notebook,或者在運行窗口中輸入jupyter notebook,即可啓動服務,注意不要關閉服務窗口,讓其在後臺運行。
打開notebook之後的界面如下圖所示,推薦將其添加到書籤欄方便以後打開哦。
3.notebook設置代碼自動補全
剛安裝的notebook界面可能與上圖界面有一點小小的區別,就是菜單欄中沒有“Nbextensions”選項卡,這個選項卡是用來設置代碼自動補全的。
具體操作命令如下,需要注意的是執行下述命令時要 提前關閉jupyter服務。
python -m pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user --skip-running-check
執行過程需要等待一小會兒,執行完成之後打開jupyter notebook
至此,一個舒服的開發環境就算搭建好啦。
4.notebook入門
(1)創建文件
(2)界面簡介
(3)notebook常用快捷鍵(windows)
<1>命令行模式
選中語句塊後 按Esc進入命令行模式
a:在當前語句塊上方插入語句塊
b:在當前語句塊下方插入語句塊
d:刪除當前語句塊
m:進入markdown編輯模式
y:進入python代碼編輯模式
ctrl+A:選中所有語句塊
<2>插入編輯模式
shift+enter :執行並選中下一語句塊
alt+enter :執行並在下方插入空語句塊
ctrl+enter :僅執行當前語句塊
<3>其他
- run命令:
- timeit和time命令:
- 使用“ ?”獲取函數/屬性說明
二、numpy入門
1.numpy簡介
numpy 是一個運行速度非常快的數學庫,主要用於數組計算,包含:
- 一個強大的N維數組對象 ndarray
- 廣播功能函數
- 整合 C/C++/Fortran 代碼的工具
- 線性代數、傅里葉變換、隨機數生成等功能
Anaconda中已經包含了numpy,只需要使用import導入即可。
2.創建和使用numpy數組
(1)數組屬性
(2)創建數組對象ndarray
NumPy 最重要的一個特點是其 N 維數組對象 ndarray,它是一系列同類型數據的集合,以 0 下標爲開始進行集合中元素的索引。
ndarray 對象是用於存放同類型元素的多維數組(與python的list不同)。ndarray 中的每個元素在內存中都有相同存儲大小的區域。
import numpy
# numpy中的數組ndarray
list_numpy= np.array([i for i in range(10)]) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# python自帶list
list_python = [i for i in range(10)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# list 轉換爲 ndarray
list_to_ndarray = np.array(list_python) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
(3)創建空矩陣/零矩陣/全一矩陣/單位矩陣
import numpy
nplist = np.zeros(10,dtype=complex)
#array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,0.+0.j, 0.+0.j])
nplist = np.ones(10,dtype=int)
#array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
nplist.reshape(2,5) #reshape()詳解見ndarray數組屬性
#array([[1, 1, 1, 1, 1],
# [1, 1, 1, 1, 1]])
np.eye(5, M=5, k=0, dtype=int)
# array([[1, 0, 0, 0, 0],
# [0, 1, 0, 0, 0],
# [0, 0, 1, 0, 0],
# [0, 0, 0, 1, 0],
# [0, 0, 0, 0, 1]])
npmatrix=np.full(shape=(2,4),fill_value=9) #指定矩陣元素
# array([[9, 9, 9, 9],
# [9, 9, 9, 9]])
np.empty([3,2], dtype = int)
# array([[ 6917529027641081856 ,5764616291768666155],
# [ 6917529027641081859 ,-5764598754299804209],
# [ 4497473538 , 844429428932120]])
(4)使用數字序列/隨機數創建矩陣
<1>使用數字序列
import numpy as np
x = np.arange(10)
# arange(start=None, stop, step=None, , dtype=None)
# [0 1 2 3 4 5 6 7 8 9]
x=np.linspace(0,10,11,retstep=True,dtype=int)
# 根據區間長度和元素個數返回一個等差數列
# def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)
# (array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), 1.0)
<2>使用隨機數
import numpy as np
x=np.random.random(10)
# 返回指定個數的[0.0, 1.0)區間內的隨機數
x=np.random.randint(0,100,15).reshape(5,3)
# 返回[0,100)內15個隨機整數,並重塑爲5*3矩陣
# [[53 62 33]
# [50 89 99]
# [37 8 30]
# [94 8 53]
# [47 50 83]]
(5)矩陣(數組)合併
<1>concatenate((a1, a2, ...), axis=0, out=None)
concatenate()函數根據指定的維度,對一個元組、列表中的list或者ndarray進行連接,函數原型:
numpy.concatenate((a1, a2, ...), axis=0)
先來看幾個例子,一個2*2的數組和一個1*2的數組,在第0維進行拼接,得到一個3*2的數組:
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
np.concatenate((a, b), axis=0)
輸出爲:
array([[1, 2],
[3, 4],
[5, 6]])
進一步,一個2*2的數組和一個2*1的數組,在第1維進行拼接,得到一個2*3的數組:
np.concatenate((a, b.T), axis=1)
輸出爲:
array([[1, 2, 5],
[3, 4, 6]])
上面兩個簡單的例子中,拼接的維度的長度是不同的,但是其他維度的長度必須是相同的,這也是使用concatenate()函數的一個基本原則,違背此規則就會報錯,例如一個2*2的數組和一個1*2的數組,在第1維進行拼接:
np.concatenate((a, b), axis=1)
上面的代碼會報錯:
ValueError: all the input array dimensions except for the concatenation axis must match exactly
<2>stack((a1, a2, ...), axis=0, out=None)
翻看了很多對stack函數進行解析的帖子,都沒有找到一個很好的解釋,要麼不知所云,要麼太過複雜,於是不得不自己動手實驗一下。
首先,用於stack的數組或者矩陣必須是同形的,也就是shape屬性相同。
Ⅰ.一維數組的stack合併
import numpy as np
a = np.array([1,2,3])
b = np.array([2,3,4])
x = np.stack([a,b],axis=0)
print(x.shape)
a b的shape都是(3,)而按照axis=0合併之後的shape是(2,3),因此stack函數是將參數數組都加上一個axis指定的維度,再在這個維度上進行concatenate()。因此上述代碼中的stack函數若將axis參數改爲1,合併之後的shape=(3,2)
Ⅱ.二維數組的stack合併
二維數組與一維數組同理
import numpy as np
a = np.array([[1,2,3]])
b = np.array([[2,3,4]])
c = np.array([[2,3,4]])
x = np.stack([a,b,c],axis=0)
print(x.shape)
# 下述代碼與上述代碼作用相同
a= a.reshape(-1,1,3)
b= b.reshape(-1,1,3)
c= c.reshape(-1,1,3)
x = np.concatenate((a,b,c),axis=0)
print(x.shape)
輸出結果:
<3>vstack(tup)
相當於stack(axis=0),行堆疊
<4>hstack(tup)
相當於stack(axis=1),列堆疊
3.numpy的矩陣運算 - universal function
ufunc是universal function的縮寫,意思是這些函數能夠作用於narray對象的每一個元素上,而不是針對narray對象操作,numpy提供了大量的ufunc的函數。這些函數在對narray進行運算的速度比使用循環或者列表推導式要快很多,但請注意,在對單個數值進行運算時,python提供的運算要比numpy效率高。
詳情請見:python科學計算之numpy——ufunc函數
注意:numpy的universal function操作符如 A+2、A*2(A是二維數組),針對ndarray數組對象纔有用,對python的list對象沒用。
注意:由於A*B等操作,是對數組元素進行運算,並非矩陣乘法,因此對於這種情況應使用np.dot(A,B)-矩陣乘法等函數。
矩陣運算詳情請見:numpy矩陣運算
4.numpy中的聚合操作(統計函數)
NumPy 提供了很多統計函數,用於從數組中查找最小元素,最大元素,百分位標準差和方差等。
詳情請見:numpy中的統計函數
5.numpy中的索引取值
(1)初級索引和切片
import numpy as np
#一維數組切片
a = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
print(a)
print(a[7:2:-1]) # [7 6 5 4 3]
print(a[2:8:2]) # [2 4 6]
print(a[3:]) # [3 4 5 6 7 8 9]
print(a[:5]) # [0 1 2 3 4]
indexs=[1,5,9] # 使用索引數組進行取值
print(a[indexs]) # [1 5 9]
# 二維數組切片
A = np.arange(12).reshape(3,4)
# A
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(A[2,3]) # 11
print(A[1:3,...])
# [[ 4 5 6 7]
# [ 8 9 10 11]]
print(A[:,:2])
# [[0 1]
# [4 5]
# [8 9]]
print(A[...,:2])
# [[0 1]
# [4 5]
# [8 9]]
# 使用索引數組進行索引
indexs = [0,2]
print(A[indexs])
# [[ 0 1 2 3]
# [ 8 9 10 11]]
rows = [0,1]
cols = [1,3]
print(A[rows,cols]) # [1 7] 第1、2行和第2、4列的交點元素
rows = [[0,0],[1,1]]
cols = [[0,2],[0,2]]
print(A[rows,cols])
# [[0 2]
# [4 6]]
(2)高級索引-布爾比較索引
在實際應用中,我們可能會遇到這樣的情況,一組m*n的二維數組,存放着m個對象的各自的n維特徵值數據,還有一個一維數組存放着m個對象的標籤,這m個標籤數據的次序與二維數組中的數據的行的順序是相同的。那我們如果想提取出具有相同標籤的的對象的特徵值數據該怎麼辦呢?布爾比較索引可以很好的解決這個問題。
numpy中的universal function不僅提供了加、減、乘、除、模這樣的運算,而且提供了布爾運算。如一維數組x>5的返回值是一個與x等長一維bool數組,元素值爲bool類型
print(np.arange(5))
print(np.arange(5)>2)
# [ 0 1 2 3 4 ]
# [False False False True True]
numpy中的數組可以通過傳入一個布爾數組進行取值,返回布爾值爲True的對應位置元素
# 布爾比較
A = np.arange(16).reshape((4,4))
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]
# [12 13 14 15]]
print(A>5)
# [[False False False False]
# [False False True True]
# [ True True True True]
# [ True True True True]]
print(A[A>5])
# [ 6 7 8 9 10 11 12 13 14 15]
三、matplotlib初探
1.matplotlib.pyplot簡介及入門
本文使用matplotlib中的pyplot模塊進行可視化編程,pyplot可以快速的繪製函數圖像或者散點圖,可以設置圖像的顏色、形狀(虛線、實線)、控制座標軸數據範圍等。
2.數據加載及數據探索
本文使用的數據集是sklearn的鳶尾花數據集
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets
#導入鳶尾花數據
iris = datasets.load_iris() # iris類似一個字典
print(iris.keys())
# dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename'])
print(iris.data)
# data: 150*4的二維數組,存放着150株鳶尾花的特徵數據[花萼的長,花萼的寬,花瓣的長,花瓣的寬]
print(iris.target)
# target: 一維數組,與data中數據一一對應,反映data中某一行數據所屬花的種類。0:Setosa鳶尾花、1:Versicolour鳶尾花、2:Virginica鳶尾花
print(iris.target_names)
# target_names:['setosa', 'versicolor', 'virginica']
print(iris.feature_names)
# feature_names:['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
將Virginica鳶尾花的數據提取出來,並將其花瓣的長和寬繪製成散點圖。
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets
#導入鳶尾花數據
iris = datasets.load_iris() # iris類似一個字典
x=iris.data[iris.target==2,2] #提取花瓣長數據
y=iris.data[iris.target==2,3] #提取花瓣寬數據
plt.scatter(x,y)
plt.xlabel("petal length (cm)")
plt.ylabel("petal width (cm)")
plt.show()
爲了查看三種不同的鳶尾花之間的差別,將4個特徵數據兩兩組合,繪製出6個散點圖。
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets
#導入鳶尾花數據
iris = datasets.load_iris() # iris類似一個字典
def drawScatter(data,plt,target,xind,yind):
gs=[] #存放3個散點圖,用於添加圖例
for i,samble,color in zip([0,1,2],"ox^",['red','yellow','blue']):
g = plt.scatter(data[target==i,xind],data[target==i,yind],marker=samble,c=color)
gs.append(g)
plt.xlabel(iris.feature_names[xind]) #添加x軸標籤
plt.ylabel(iris.feature_names[yind]) #添加y軸標籤
plt.title(iris.feature_names[xind]+" and "+iris.feature_names[yind]) #添加標題
plt.legend(gs,iris.target_names) #顯示圖例
num=1;# 計數,當前是第num個圖
for i in range(4):
for j in range(i+1,4):
plt.subplot(2,3,num) # 共有2*3=6個圖,將窗口分爲2行3列
drawScatter(iris.data,plt,iris.target,i,j)
num=num+1
plt.show()
致謝與說明
首先,感謝直接或間接幫助我寫完這篇文章的博主表示感謝,由於參考文章過多就不一一列舉了。
其次,筆者剛剛開始進入機器學習,寫作本文的目的也主要是幫助自己理解知識,同時也希望能夠幫助同樣剛剛開始學習機器學習的小夥伴。
最後,由於筆者剛剛開始學習,文章中難免有錯誤的地方,請讀者不吝指出。