Matplotlib&Numpy

Matplotlib

  • 是專門用於開發2D圖表(包括3D圖表)
  • 以漸進、互動式方式實現數據可視化

實現一個簡單的Matplotlib畫圖

①導入:matplotlib.pytplot包含了一系列類似於matlab的畫圖函數。

②圖形繪製流程:

創建畫布 — plt.figure()

繪製影像 — plt.plot(x, y)

顯示影像 — plt.show()

import matplotlib.pyplot as plt

# 1.創建畫布
plt.figure()

# 2.繪製折線圖
plt.plot([1, 2, 3, 4, 5, 6 ,7], [17,17,18,15,11,11,13])

# 3.顯示影像
plt.show()

輸出:

 

 

擴展畫圖的功能

添加自定義x,y刻度

  • plt.xticks(x, **kwargs)

    x:要顯示的刻度值

  • plt.yticks(y, **kwargs)

    y:要顯示的刻度值

#添加x,y軸刻度
x_ticket=["11點{}分".format(i) for i in x]
y_ticket=range(60)
#修改x,y軸的坐標刻度線是
plt.xticks(x[::5],x_ticket[::5])
plt.yticks(y_ticket[::5])

 

中文顯示問題解決

from pylab import mpl

mpl.rcParams["font.sans-serif"]=["SimHei"]
mpl.rcParams["axes.unicode_minus"]=False

添加網格顯示

#添加網格顯示
plt.grid(True,linestyle='--',alpha=0.5)

 

 

添加描述資訊

#添加描述資訊
plt.xlabel("時間")
plt.ylabel("溫度")
plt.title("中午11點-12點某城市溫度變化圖",fontsize=20)

 

 

影像保存

#保存圖片
plt.savefig("./test.png")

在一個坐標系中繪製多個影像

只要多次plot就行

x=range(60)
y=[random.uniform(15,18) for i in x]
y2=[random.uniform(3,5) for i in x]
#繪製畫布
plt.figure(figsize=(10,8),dpi=100)
#繪製影像
plt.plot(x,y,label="上海")
plt.plot(x,y2,color='r',linestyle='--',label="北京")

設置圖形風格

顏色字元 風格字元
r 紅色 – 實線
g 綠色 – – 虛線
b 藍色 -. 點劃線
w 白色 : 點虛線
c 青色 ‘ ‘ 留空、空格
m 洋紅  
y 黃色  
k 黑色

 

 

 

 

 

 

 

 

 

 

顯示圖例

如果只在plt.plot()中設置label還不能最終顯示出圖例,還需要通過plt.legend()將圖例顯示出來。

import matplotlib.pyplot as plt
import random
from pylab import mpl

mpl.rcParams["font.sans-serif"]=["SimHei"]
mpl.rcParams["axes.unicode_minus"]=False
x=range(60)
y=[random.uniform(15,18) for i in x]
y2=[random.uniform(3,5) for i in x]
#繪製畫布
plt.figure(figsize=(10,8),dpi=100)
#繪製影像
plt.plot(x,y,label="上海")
plt.plot(x,y2,color='r',linestyle='--',label="北京")
#添加網格顯示
plt.grid(True,linestyle='--',alpha=0.5)
#添加描述資訊
plt.xlabel("時間")
plt.ylabel("溫度")
plt.title("中午11點-12點某城市溫度變化圖",fontsize=20)
#添加x,y軸刻度
x_ticket=["11點{}分".format(i) for i in x]
y_ticket=range(60)
#修改x,y軸的坐標刻度線是
plt.xticks(x[::5],x_ticket[::5])
plt.yticks(y_ticket[::5])
#保存圖片
plt.savefig("./test.png")
#顯示圖例
plt.legend(loc="best")
plt.show()

 

 

多個坐標系顯示— plt.subplots(面向對象的畫圖方法)

matplotlib.pyplot.subplots(nrows=1, ncols=1, **fig_kw) 創建一個帶有多個axes(坐標系/繪圖區)的圖

import matplotlib.pyplot as plt
import random
from pylab import mpl

mpl.rcParams["font.sans-serif"]=["SimHei"]
mpl.rcParams["axes.unicode_minus"]=False
x=range(60)
y=[random.uniform(15,18) for i in x]
y2=[random.uniform(3,5) for i in x]
#繪製畫布
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(30,15),dpi=100)
#繪製影像
axes[0].plot(x,y,label="上海")
axes[1].plot(x,y2,color='r',linestyle='--',label="北京")
#添加網格顯示
axes[0].grid(True,linestyle='--',alpha=0.5)
axes[1].grid(True,linestyle='--',alpha=0.5)
# #添加描述資訊
axes[0].set_xlabel("時間")
axes[0].set_ylabel("溫度")
axes[0].set_title("中午11點-12點某城市溫度變化圖",fontsize=20)
axes[1].set_xlabel("時間")
axes[1].set_ylabel("溫度")
axes[1].set_title("中午11點-12點某城市溫度變化圖",fontsize=20)
#添加x,y軸刻度
x_ticket=["11點{}分".format(i) for i in x]
y_ticket=range(60)
#修改x,y軸的坐標刻度線是
axes[0].set_xticks(x[::5])
axes[0].set_yticks(y_ticket[::5])
axes[0].set_xticklabels(x_ticket[::5])
axes[1].set_xticks(x[::5])
axes[1].set_yticks(y_ticket[::5])
axes[1].set_xticklabels(x_ticket[::5])
# #保存圖片
plt.savefig("./test.png")
# #顯示圖例
axes[0].legend(loc="best")
axes[1].legend(loc="best")
plt.show()

 

 畫各種數學函數影像

正弦(sin),餘弦(cos),正切(tan),反正弦(arcsin),反餘弦(arccos),反正切(arctan)

import numpy as np
import matplotlib.pyplot as plt
# 0.準備數據
x = np.linspace(-10, 10, 1000)
y = np.sin(x)

# 1.創建畫布
plt.figure(figsize=(20, 8), dpi=100)

# 2.繪製函數影像
plt.plot(x, y)
# 2.1 添加網格顯示
plt.grid()

# 3.顯示影像
plt.show()

 

制折線圖、散點圖、柱狀圖、直方圖、餅圖

折線圖:以折線的上升或下降來表示統計數量的增減變化的統計圖

特點:能夠顯示數據的變化趨勢,反映事物的變化情況。(變化)

api:plt.plot(x, y)

 

散點圖:用兩組數據構成多個坐標點,考察坐標點的分布,判斷兩變數之間是否存在某種關聯或總結坐標點的分布模式。

特點:判斷變數之間是否存在數量關聯趨勢,展示離群點(分布規律)

api:plt.scatter(x, y)

import matplotlib.pyplot as plt
from pylab import mpl

mpl.rcParams["font.sans-serif"]=["SimHei"]
mpl.rcParams["axes.unicode_minus"]=False

x = [225.98, 247.07, 253.14, 457.85, 241.58, 301.01,  20.67, 288.64,
       163.56, 120.06, 207.83, 342.75, 147.9 ,  53.06, 224.72,  29.51,
        21.61, 483.21, 245.25, 399.25, 343.35]
y = [196.63, 203.88, 210.75, 372.74, 202.41, 247.61,  24.9 , 239.34,
       140.32, 104.15, 176.84, 288.23, 128.79,  49.64, 191.74,  33.1 ,
        30.74, 400.02, 205.35, 330.64, 283.45]
#創建畫布
plt.figure(figsize=(20,8),dpi=100)
#繪製影像
plt.scatter(x,y)
#影像顯示
plt.show()

 

 

柱狀圖:排列在工作表的列或行中的數據可以繪製到柱狀圖中。

特點:繪製連離散的數據,能夠一眼看出各個數據的大小,比較數據之間的差別。(統計/對比)

api:plt.bar(x, width, align=’center’, **kwargs)

Parameters:    
x : 需要傳遞的數據

width : 柱狀圖的寬度

align : 每個柱狀圖的位置對齊方式
    {『center』, 『edge』}, optional, default: 『center』

**kwargs :
color:選擇柱狀圖的顏色
import matplotlib.pyplot as plt
from pylab import mpl

mpl.rcParams["font.sans-serif"]=["SimHei"]
mpl.rcParams["axes.unicode_minus"]=False

# 電影名字
movie_name = ['雷神3:諸神黃昏','正義聯盟','東方快車謀殺案','尋夢環遊記','全球風暴','降魔傳','追捕','七十七天','密戰','狂獸','其它']
# 橫坐標
x = range(len(movie_name))
# 票房數據
y = [73853,57767,22354,15969,14839,8725,8716,8318,7916,6764,52222]

#創建畫布
plt.figure(figsize=(20,8),dpi=100)
#繪製影像
plt.bar(x,y,color=['b','r','g','y','c','m','y','k','c','g','b'],width=0.7)
#修改x軸顯示
plt.xticks(x,movie_name)
#添加網格
plt.grid(linestyle="--",alpha=0.8)
#添加標題
plt.title("電影票房收入對比")
#影像顯示
plt.show()

 

 

直方圖:由一系列高度不等的縱向條紋或線段表示數據分布的情況。 一般用橫軸表示數據範圍,縱軸表示分布情況。

特點:繪製連續性的數據展示一組或者多組數據的分布狀況(統計)

api:matplotlib.pyplot.hist(x, bins=None)

Parameters:    
x : 需要傳遞的數據
bins : 組距

import matplotlib.pyplot as plt
import numpy as np
from pylab import mpl

mpl.rcParams["font.sans-serif"]=["SimHei"]
mpl.rcParams["axes.unicode_minus"]=False
plt.figure(figsize=(20,8),dpi=100)
x2=np.random.uniform(-10,10,1000)
plt.hist(x2,1000)#x2為使用的數據,1000為劃分的區間數
plt.show()

 

 

餅圖:用於表示不同分類的佔比情況,通過弧度大小來對比各種分類。

特點:分類數據的佔比情況(佔比)

api:plt.pie(x, labels=,autopct=,colors)

Parameters:  
x:數量,自動算百分比
labels:每部分名稱
autopct:佔比顯示指定%1.2f%%
colors:每部分顏色
import matplotlib.pyplot as plt
import numpy as np
from pylab import mpl

mpl.rcParams["font.sans-serif"]=["SimHei"]
mpl.rcParams["axes.unicode_minus"]=False
plt.figure(figsize=(20,8),dpi=100)

x=[10,20,30,40]
labels=["演算法","網頁","人工智慧","大數據"]

colors=["r","g","y","b"]
plt.pie(x,labels=labels,autopct="%1.2f%%",colors=colors)
# 顯示圖例
plt.legend()
plt.show()

 

 

Numpy

Numpy(Numerical Python)是一個開源的Python科學計算庫,用於快速處理任意維度的數組。

Numpy支援常見的數組和矩陣操作。對於同樣的數值計算任務,使用Numpy比直接使用Python要簡潔的多。

Numpy使用ndarray對象來處理多維數組,該對象是一個快速而靈活的大數據容器。

簡單認識

import numpy as np
#二維數組
score=np.array([[80, 89, 86, 67, 79],
[78, 97, 89, 67, 81],
[90, 94, 78, 67, 74],
[91, 91, 90, 67, 69],
[76, 87, 75, 67, 86],
[70, 79, 84, 67, 84],
[94, 92, 93, 67, 64],
[86, 85, 83, 67, 80]])
print(score.shape)#數組維度的元組
print(score.ndim)#數組維數
print(score.size)#數組中的元素數量
print(score.itemsize)#一個數組元素的長度
print(score.dtype)#數組元素的類型
#三維數組,自定義數據類型
c=np.array([[[80, 89, 86, 67, 79],
[78, 97, 89, 67, 81],
[90, 94, 78, 67, 74],
[91, 91, 90, 67, 69]],
[[76, 87, 75, 67, 86],
[70, 79, 84, 67, 84],
[94, 92, 93, 67, 64],
[86, 85, 83, 67, 80]]],dtype=np.float32)
print(c)
print(c.ndim)
print(c.shape)

輸出:

(8, 5)
2
40
4
int32
[[[80. 89. 86. 67. 79.]
[78. 97. 89. 67. 81.]
[90. 94. 78. 67. 74.]
[91. 91. 90. 67. 69.]]

[[76. 87. 75. 67. 86.]
[70. 79. 84. 67. 84.]
[94. 92. 93. 67. 64.]
[86. 85. 83. 67. 80.]]]
3
(2, 4, 5)

深拷貝與淺拷貝

import numpy as np

# a=np.ones([3,3])
# print(a)
# b=np.zeros_like(a)
# print(b)

#從現有數組生成
k=np.array([[1,2,3],[4,5,6]])
#深拷貝
k1=np.array(k)
#淺拷貝
k2=np.asarray(k)
print(k1)
print(k2)
k[0,0]=100
#源數據改變,因此淺拷貝的數據也會改變
print(k1)
print(k2)

輸出:

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

間隔數組,等差數組,等比數組

import numpy as np
#生成等間隔的數組
a=np.linspace(0,100,11)
print(a)
#創建等差數組-指定步長
b=np.arange(10,50,2)
print(b)
#創建等比數列
#start:10**start次方開始,stop:10**stop次方結束,num為生成的樣本個數
c=np.logspace(1,3,100)
print(c)

輸出:

[ 0. 10. 20. 30. 40. 50. 60. 70. 80. 90. 100.]
[10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48]
[ 10. 10.47615753 10.97498765 11.49756995 12.0450354
12.61856883 13.21941148 13.84886371 14.50828778 15.19911083
15.92282793 16.68100537 17.475284 18.3073828 19.17910262
20.09233003 21.04904145 22.0513074 23.101297 24.20128265
25.35364494 26.56087783 27.82559402 29.15053063 30.53855509
31.99267138 33.51602651 35.11191734 36.78379772 38.53528594
40.37017259 42.29242874 44.30621458 46.41588834 48.6260158
50.94138015 53.36699231 55.90810183 58.57020818 61.35907273
64.28073117 67.34150658 70.54802311 73.90722034 77.42636827
81.11308308 84.97534359 89.02150854 93.26033469 97.70099573
102.35310219 107.2267222 112.3324033 117.68119524 123.28467394
129.1549665 135.30477746 141.74741629 148.49682623 155.56761439
162.97508346 170.73526475 178.86495291 187.38174229 196.304065
205.65123083 215.443469 225.70197196 236.44894126 247.7076356
259.50242114 271.85882427 284.80358684 298.36472403 312.57158497
327.45491629 343.04692863 359.38136638 376.49358068 394.42060594
413.20124001 432.87612811 453.48785081 475.08101621 497.70235643
521.4008288 546.22772177 572.23676594 599.48425032 628.02914418
657.93322466 689.26121043 722.08090184 756.46332755 792.48289835
830.21756813 869.74900262 911.16275612 954.54845666 1000. ]

生成0和1的數組

import numpy as np

a=np.ones([3,3])
print(a)
b=np.zeros_like(a)
print(b)

輸出:

[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]

生成隨機數組

import matplotlib.pyplot as plt
import numpy as np

#生成一個正態分布
#0為均值,1為標準差,這是一個標準的正態分布
x1=np.random.normal(0,1,100000000)
plt.figure()
plt.hist(x1,1000)
plt.show()

#生成一個四行五列的正態分布表
stack=np.random.normal(0,1,[4,5])
print(stack)

#均勻分布
#上限為1,下限為-1,生成10000000個隨機數
x2=np.random.uniform(-1,1,10000000)
print(x2)
plt.figure()
plt.hist(x2,1000)#x2為使用的數據,1000為劃分的區間數
plt.show()

 

 

[[ 0.21734627 -0.97992775 0.24635965 -0.52524527 0.61409397]
[-0.42891216 0.07972822 -0.09477911 1.77777235 -0.09798548]
[ 0.30071645 -0.95531024 0.30922396 -0.72969828 -0.43364537]
[-1.27946259 -1.05671799 0.74995682 0.51016288 0.50191553]]

 

 

 

數組的索引、切片

一維、二維、三維的數組如何索引?

  • 直接進行索引,切片
  • 對象[:, :] — 先行後列
import numpy as np


a=np.random.normal(0,1,(4,5))
print(a)
print(a[0:3,0:3])

# 三維
a1 = np.array([ [[1,2,3],[4,5,6]], [[12,3,34],[5,6,7]]])
print(a1[0,0,1])

輸出:

[[-0.8475957 0.59500006 -0.99042764 -1.47068488 1.04488987]
[ 1.05759779 -0.34656605 0.25075867 1.26481382 -0.02561291]
[ 0.00384902 0.53486762 -0.94276903 -0.33453538 1.447024 ]
[ 0.60627864 0.26352157 0.61437243 -1.0099516 -1.34009347]]
[[-0.8475957 0.59500006 -0.99042764]
[ 1.05759779 -0.34656605 0.25075867]
[ 0.00384902 0.53486762 -0.94276903]]
2

形狀修改

import numpy as np

#創建數據
a=np.random.normal(0,1,(4,5))
print("源數據:{}".format(a))
#reshape:返回一個具有相同數據域,但shape不一樣的視圖
b=a.reshape([5,4])
print("reshape為5行4列的新數據:{}".format(b))
c=a.reshape([-1,2])
print("reshape為?行2列的新數據:{}".format(c))
d=a.reshape([2,-1])
print("reshape為2行?列的新數據:{}".format(d))

#resize:修改數組本身的形狀(需要保持元素個數前後相同)
a.resize([10,2])
print("修改本身為10行2列後的數據:{}".format(a))

#轉置
a=a.T
print("轉置後的數據:{}".format(a))
#修改數組的數據類型
a=a.astype(np.int32)
print("修改數據的類型為int:{}".format(a))
#轉為字元串
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[12, 3, 34], [5, 6, 7]]])
print("轉為字元串:{}".format(arr.tostring()))
#數組去重
tmp=np.array([[1,2,3,4],[3,4,5,6]])
print("數組去重後的數據:{}".format(np.unique(tmp)))

源數據:[[-1.01605099 0.04340228 -0.13464495 1.15063668 -0.6123171 ]
[-2.47248818 0.92994026 -0.85258242 0.1856697 1.41896786]
[ 1.87231721 -0.26889703 -0.07252063 -0.40996587 0.21071932]
[-0.67559295 1.39530076 -0.20394447 -0.39996382 0.03839303]]
reshape為5行4列的新數據:[[-1.01605099 0.04340228 -0.13464495 1.15063668]
[-0.6123171 -2.47248818 0.92994026 -0.85258242]
[ 0.1856697 1.41896786 1.87231721 -0.26889703]
[-0.07252063 -0.40996587 0.21071932 -0.67559295]
[ 1.39530076 -0.20394447 -0.39996382 0.03839303]]
reshape為?行2列的新數據:[[-1.01605099 0.04340228]
[-0.13464495 1.15063668]
[-0.6123171 -2.47248818]
[ 0.92994026 -0.85258242]
[ 0.1856697 1.41896786]
[ 1.87231721 -0.26889703]
[-0.07252063 -0.40996587]
[ 0.21071932 -0.67559295]
[ 1.39530076 -0.20394447]
[-0.39996382 0.03839303]]
reshape為2行?列的新數據:[[-1.01605099 0.04340228 -0.13464495 1.15063668 -0.6123171 -2.47248818
0.92994026 -0.85258242 0.1856697 1.41896786]
[ 1.87231721 -0.26889703 -0.07252063 -0.40996587 0.21071932 -0.67559295
1.39530076 -0.20394447 -0.39996382 0.03839303]]
修改本身為10行2列後的數據:[[-1.01605099 0.04340228]
[-0.13464495 1.15063668]
[-0.6123171 -2.47248818]
[ 0.92994026 -0.85258242]
[ 0.1856697 1.41896786]
[ 1.87231721 -0.26889703]
[-0.07252063 -0.40996587]
[ 0.21071932 -0.67559295]
[ 1.39530076 -0.20394447]
[-0.39996382 0.03839303]]
轉置後的數據:[[-1.01605099 -0.13464495 -0.6123171 0.92994026 0.1856697 1.87231721
-0.07252063 0.21071932 1.39530076 -0.39996382]
[ 0.04340228 1.15063668 -2.47248818 -0.85258242 1.41896786 -0.26889703
-0.40996587 -0.67559295 -0.20394447 0.03839303]]
修改數據的類型為int:[[-1 0 0 0 0 1 0 0 1 0]
[ 0 1 -2 0 1 0 0 0 0 0]]
轉為字元串:b’\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x0c\x00\x00\x00\x03\x00\x00\x00″\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00′
數組去重後的數據:[1 2 3 4 5 6]

array運算

import numpy as np

score=np.random.randint(40,100,(10,5))
print(score)
print()
test_score=score[6:,0:5]
# 邏輯判斷, 如果成績大於60就標記為True 否則為False
print(test_score>60)
# BOOL賦值, 將滿足條件的設置為指定的值-布爾索引
test_score[test_score>60]=1
print(test_score)

#通用判斷函數
# 判斷前兩名同學的成績[0:2, :]是否全及格
print(np.all(score[0:2,:]>60))
# 判斷前兩名同學的成績[0:2, :]是否有大於90分的
print(np.any(score[0:2,:]>90))

#三元運算符
temp=score[:4,:4]
print(temp)
print(np.where(temp>60,1,0))
# #三元運算的與操作
print(np.where(np.logical_and(temp>60,temp<90),1,0))
# #三元運算的或操作
print(np.where(np.logical_or(temp>90,temp<60),1,0))

#統計運算
tmp=score[:4,:]
print(tmp)
#最大值
print("最大值:"+str(np.max(tmp)))
#平均值
print("平均值:"+str(np.mean(tmp)))
#中位數
print("中位數:{}".format(np.median(tmp)))
#標準差
print("標準差:{}".format(np.std(tmp)))
#方差
print("方差:{}".format(np.var(tmp)))
#每列的最大值
print("每列的最大值:"+str(np.max(tmp,axis=0)))
#每行的最大值
print("每行的最大值:"+str(np.max(tmp,axis=1)))
#最大值的下標
print("最大值的下標:"+str(np.argmax(tmp)))
#每列的最大值下標
print("每列的最大值下標:"+str(np.argmax(tmp,axis=0)))
#最小值下標
print("最小值下標:"+str(np.argmin(tmp)))
#每行的最小值下標
print("每行的最小值下標:"+str(np.argmin(tmp,axis=1)))

數組間的運算

import numpy as np
#數組運算
a=np.array([[1,2,3],[3,4,5]])
print(a*3)
#列表運算
b=[1,2,3]
print(b*3)
#數組間的運算,要滿足廣播機制
#維度相等
#shape對應的地方為1
arr1 = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
print(np.shape(arr1))
arr2 = np.array([[1], [3]])
print(np.shape(arr2))
print(arr1+arr2)

[[ 3 6 9]
[ 9 12 15]]
[1, 2, 3, 1, 2, 3, 1, 2, 3]
(2, 6)
(2, 1)
[[2 3 4 3 2 5]
[8 9 4 5 6 4]]

矩陣乘法

np.matmul和np.dot的區別:

二者都是矩陣乘法。 np.matmul中禁止矩陣與標量的乘法。 在矢量乘矢量的內積運算中,np.matmul與np.dot沒有區別。

import numpy as np

a = np.array([[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]])
b=np.array([[0.7],[0.3]])
print(np.dot(a,b))
print(np.matmul(a,b))
c=10
print(np.dot(c,a))

輸出:

[[81.8]
[81.4]
[82.9]
[90. ]
[84.8]
[84.4]
[78.6]
[92.6]]
[[81.8]
[81.4]
[82.9]
[90. ]
[84.8]
[84.4]
[78.6]
[92.6]]
[[800 860]
[820 800]
[850 780]
[900 900]
[860 820]
[820 900]
[780 800]
[920 940]]