返回文章列表

NumPy Matplotlib 資料分析與視覺化

本文探討 NumPy 和 Matplotlib 在資料分析和視覺化中的應用,涵蓋標準差計算、常態分佈特性、直方圖繪製、趨勢線擬合以及圖表樣式設定等技巧。文章以實際案例說明如何使用 NumPy 進行資料處理和分析,並結合 Matplotlib

資料分析 Python

NumPy 提供了強大的陣列運算功能,方便進行資料處理和分析,例如計算標準差、生成常態分佈資料等。Matplotlib 則可以將這些資料以圖表的形式呈現,例如直方圖、線圖等,更直觀地展現資料的分佈和趨勢。結合兩者,可以有效地進行資料分析和視覺化。此外,Matplotlib 還支援多種圖表型別和樣式設定,例如線條樣式、顏色、標記等,可以根據需求客製化圖表,提升圖表的美觀度和資訊傳達效率。

統計資料收集與報告

在資料分析領域,標準差(Standard Deviation)是一個重要的衡量資料分散程度的指標。NumPy 函式庫提供了一個方便的函式來計算任何陣列的標準差值。

標準差的計算與意義

假設我們有一個簡單的陣列:

>>> import numpy as np
>>> a = np.array([1., 4., 3., 5., 6., 2.])
>>> a
array([1., 4., 3., 5., 6., 2.])
>>> np.std(a)
1.707825127659933

內容解密:

  • np.array([1., 4., 3., 5., 6., 2.]) 建立了一個包含浮點數的 NumPy 陣列。
  • np.std(a) 計算陣列 a 的標準差,結果為 1.707825127659933,表示資料點相對於平均值的分散程度。

常態分佈與標準差的關係

大多數現實世界的資料雖然看似隨機,但通常遵循常態分佈(Normal Distribution)。例如,一個國家的人口平均身高可能是 180 公分,大多數人的身高會接近這個值,越遠離這個平均值的個體越少。常態分佈由兩個引數定義:平均值(μ)和標準差(σ)。

  • 平均值(μ)代表分佈的中點。
  • 標準差(σ)決定了分佈的「扁平程度」。標準差越大,資料越分散。

根據常態分佈的特性:

  • 約 68% 的資料落在平均值的一個標準差範圍內。
  • 約 95% 的資料落在平均值的兩個標準差範圍內。
  • 約 99.7% 的資料落在平均值的三個標準差範圍內。

大型資料集的分析例項

假設我們生成一個包含 10,000 個隨機數的資料集,這些數字遵循平均值(μ)為 4、標準差(σ)為 0.9 的常態分佈。將這些數字歸類別到不同的區間(共 28 個區間),並對區間值進行歸一化處理,使其總和等於 1。這樣每個區間的值代表了資料出現在該區間的機率或百分比。

圖表視覺化與解讀

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title NumPy Matplotlib 資料分析與視覺化

package "統計分析流程" {
    package "資料收集" {
        component [樣本資料] as sample
        component [母體資料] as population
    }

    package "描述統計" {
        component [平均數/中位數] as central
        component [標準差/變異數] as dispersion
        component [分佈形狀] as shape
    }

    package "推論統計" {
        component [假設檢定] as hypothesis
        component [信賴區間] as confidence
        component [迴歸分析] as regression
    }
}

sample --> central : 計算
sample --> dispersion : 計算
central --> hypothesis : 檢驗
dispersion --> confidence : 估計
hypothesis --> regression : 建模

note right of hypothesis
  H0: 虛無假設
  H1: 對立假設
  α: 顯著水準
end note

@enduml

此圖示展示了從生成常態分佈資料到繪製直方圖並新增近似函式線和標準差帶的流程。

圖表解析:

  • 直方圖顯示了資料的分佈情況,近似於理論上的常態分佈形狀。
  • 平均值(μ = 4)用垂直線標示,三個標準差帶(±1σ、±2σ、±3σ)清晰地展示了資料的集中程度。

系統管理中的應用

雖然我們花了很多時間討論科學現象,但這與系統管理有什麼關係?大多數自然過程都是隨機事件,但它們通常圍繞某些值聚集。例如,高速公路上的汽車平均速度不會是固定的,有些車會開得快一些,有些則慢一些,但大多數車速會接近平均值。測量足夠多的車速資料後,你會得到一個類別似常態分佈圖的速度分佈形狀。

統計資料收集與報告

在系統管理中,瞭解系統負載的變化趨勢對於預測和應對可能的系統過載至關重要。系統負載的變化可以用統計學中的機率分佈來描述。假設系統負載平均值圍繞某個特定值波動,我們可以使用正態分佈(Normal Distribution)來模擬這種行為。

系統負載的正態分佈模型

正態分佈是一種常見的機率分佈,其特點是資料圍繞平均值(mean)對稱分佈,並且資料越遠離平均值,出現的機率越低。在系統負載的例子中,我們可以假設負載平均值遵循正態分佈。

標準差與變異數

在正態分佈中,標準差(standard deviation)和變異數(variance)是兩個重要的引數。標準差衡量資料的離散程度,而變異數則是標準差的平方。利用這兩個引數,我們可以計算出系統負載在某個範圍內的機率。

例如,假設某個四核伺服器的負載平均值遵循正態分佈,平均值為4,標準差為1。那麼,根據正態分佈的特性,我們可以計算出負載平均值在3到5之間的機率約為68%,而在2到6之間的機率則高於95%。這意味著,如果某次測量的負載平均值超出這個範圍,我們就有可能需要關注,因為這可能指示系統行為異常。

直方圖計算

除了標準差和變異數之外,直方圖(histogram)也是瞭解資料分佈的重要工具。直方圖可以將資料分組並顯示每組資料的頻率。在NumPy中,可以使用np.histogram()函式來計算直方圖。

import numpy as np

# 生成1000個符合正態分佈的隨機數
a = np.random.randn(1000)

# 計算直方圖,分成8組並進行歸一化
h, b = np.histogram(a, bins=8, density=True)

print("直方圖頻率:", h)
print("分組邊界:", b)

內容解密:

  1. np.random.randn(1000):生成1000個符合標準正態分佈(平均值為0,標準差為1)的隨機數。
  2. np.histogram():計算輸入資料的直方圖。
    • bins=8:將資料分成8組。
    • density=True:對直方圖進行歸一化,使其面積總和為1。
  3. 傳回的h是每組的頻率,b是分組的邊界。

尋找資料集的趨勢線

在收集系統資料時,我們經常需要了解某個指標(如CPU負載)是否隨時間變化而呈現上升或下降趨勢。簡單的方法是觀察資料圖表,但當趨勢不明顯時,我們需要藉助統計方法。

迴歸分析

迴歸分析(Regression Analysis)是一種用於找出資料趨勢的方法。其中,最小二乘法(Method of Least Squares)是一種常見的迴歸分析技術,用於擬合資料集的最佳曲線。在簡單的一元線性迴歸中,這條曲線是一條直線,其斜率表示趨勢的方向和強度。

在NumPy中,可以使用np.polyfit()函式來計算一元線性迴歸的引數。

import numpy as np
import matplotlib.pyplot as plt

# 生成x軸資料
x = np.arange(100)

# 生成y軸資料,加入一些隨機噪聲和線性趨勢
y = np.random.normal(4., 0.9, 100) + x/40

# 進行一元線性迴歸
a, b = np.polyfit(x, y, 1)

print(f"趨勢線方程:y = {a:.3f}x + {b:.3f}")

# 繪製原始資料點和趨勢線
plt.scatter(x, y, label='原始資料')
plt.plot(x, a*x + b, color='red', label='趨勢線')
plt.legend()
plt.show()

內容解密:

  1. np.arange(100):生成從0到99的整數序列作為x軸資料。
  2. np.random.normal(4., 0.9, 100) + x/40:生成y軸資料,包含隨機噪聲和線性趨勢。
  3. np.polyfit(x, y, 1):進行一元線性迴歸,傳回趨勢線的斜率和截距。
  4. plt.scatter()plt.plot():分別繪製原始資料點和趨勢線。

資料儲存與讀取:NumPy 的輸入輸出功能

在某些情況下,我們需要將資料寫入檔案以便後續處理。NumPy 提供了多種輸入輸出程式來實作此目的。以下範例展示如何將資料儲存到文字檔案,並使用逗號作為分隔符。

將資料儲存到文字檔案

首先,我們建立一個 4x4 的陣列,並將其儲存到名為 data.txt 的檔案中。

import numpy as np

# 建立一個 4x4 的陣列
a = np.arange(16).reshape(4, 4)
print(a)

# 將陣列儲存到檔案中,使用逗號作為分隔符
np.savetxt('data.txt', a, fmt="%G", delimiter=',')

# 從檔案中讀取資料
b = np.loadtxt('data.txt', delimiter=',')
print(b)

內容解密:

  1. np.arange(16).reshape(4, 4):建立一個包含 0 到 15 的一維陣列,並將其重塑為 4x4 的二維陣列。
  2. np.savetxt('data.txt', a, fmt="%G", delimiter=','):將陣列 a 儲存到 data.txt 檔案中,使用逗號作為分隔符,fmt="%G" 指定了輸出的格式。
  3. np.loadtxt('data.txt', delimiter=','):從 data.txt 檔案中讀取資料,並將其轉換為 NumPy 陣列,使用逗號作為分隔符。

許多流行的工具,如 Excel,都能理解這種格式,因此可以使用此方法匯出資料並與使用不同工具的其他人交換檔案。

使用 matplotlib 表示資料

matplotlib 是另一個 Python 函式庫,主要用於建立和繪製各種科學圖表。它允許生成和儲存影像檔案,也帶有具有縮放和平移選項的圖形介面。該函式庫提供了產生 2D 和 3D 圖的功能。

安裝 matplotlib

一般來說,有兩種安裝 matplotlib 的選項:使用 Python Package Index (PyPI) 安裝工具 (pip) 或從原始碼構建套件。以下是從 PyPI 安裝函式庫的命令:

sudo pip install matplotlib

建議從最新的原始碼套件構建函式庫,以確保獲得最新版本。首先,從 SourceForge 儲存函式庫下載原始碼,然後解壓縮並執行以下命令來構建和安裝 matplotlib 模組:

python setup.py build
sudo python setup.py install

根據 Linux 安裝的不同,可能還需要安裝 matplotlib 所依賴的一些額外套件。安裝完成後,可以透過執行以下命令來檢查函式庫是否正常運作:

import matplotlib
print(matplotlib.__version__)

matplotlib 的結構

matplotlib API 分為三層責任:

  1. matplotlib.backend_bases.FigureCanvas 物件,代表繪製圖形的區域。
  2. matplotlib.backend_bases.Renderer 物件,知道如何在 FigureCanvas 物件上繪圖。
  3. matplotlib.artist.Artist 物件,知道如何使用 Renderer 物件。

大多數情況下,我們只需要使用 Artist 物件。Artist 分為兩種型別:繪圖原語和容器。原語是代表要繪製的物件的物件,如線條、文字、矩形等。容器是包含原語的物件。

繪製圖形

Subplot 類別的 plot() 方法是繪製線條或標記的常用方法。以下範例展示如何繪製正弦函式圖形。

import matplotlib.pyplot as plt
import numpy as np

# 建立一個圖形物件
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

# 建立 x 和 y 的值
x = np.arange(100)
y = np.sin(2 * np.pi * x / 100)

# 繪製 y 對 x 的圖形
ax.plot(y)

# 顯示圖形
plt.show()

內容解密:

  1. fig = plt.figure():建立一個新的圖形物件。
  2. ax = fig.add_subplot(1, 1, 1):在圖形中新增一個子圖。
  3. x = np.arange(100)y = np.sin(2 * np.pi * x / 100):計算正弦函式的值。
  4. ax.plot(y):繪製 y 對 x 的圖形。
  5. plt.show():顯示圖形。

如果在具有 X 視窗管理員的系統上執行此指令碼,將在一個獨立的視窗中看到繪製的圖形,並可以使用視窗功能,如平移和縮放,以及儲存和列印檔案。

第11章:統計資料收集與報告

改變繪圖原語的外觀

plot() 函式的完整語法包括兩個座標陣列 xy,並指定繪圖格式,如繪圖顏色和樣式。以下程式碼繪製與清單 11-1 相同的圖形,但使用紅色虛線表示,由 r 快捷鍵指定顏色和 : 快捷鍵指定線型。

x = np.arange(100)
y = np.sin(2 * np.pi * x / 100)
ax.plot(x, y, 'r:')

您也可以使用關鍵字引數來指定圖形的格式和繪圖顏色。

ax.plot(x, y, linestyle='dashed', color='blue')

表 11-1:圖形樣式格式化字元和關鍵字引數

樣式快捷鍵關鍵字引數描述
-linestyle=‘solid’實線
linestyle=‘dashed’虛線
:linestyle=‘dotted’點線
-.linestyle=‘dash_dot’虛線和點線
Omarker=‘circle’圓形標記(不連線線)
.marker=‘dot’點標記(不連線線)
*marker=‘star’星形標記(不連線線)
+marker=‘plus’加號標記(不連線線)
Xmarker=‘x’X 標記(不連線線)

內容解密:

  1. plot() 函式允許透過快捷鍵或關鍵字引數來設定線條樣式和顏色。
  2. 使用快捷鍵時,顏色選項有限;而使用關鍵字引數時,顏色選擇更多。
  3. 可以透過 HTML 十六進位字串或 RGB 元組來指定顏色。
  4. 圖形樣式的設定對於視覺化資料至關重要,能夠提升圖表的可讀性和美觀度。

繪製條形圖和使用多個軸

另一種常用的繪圖方法是使用 bar() 方法建立條形原語。清單 11-2 示範瞭如何建立一個包含兩個圖形的繪圖,第一個圖形使用極座標系統,第二個使用笛卡爾座標系統。

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(2, 1, 1, polar=True)
x = np.arange(25)
y = np.sin(2 * np.pi * x / 25)
ax.bar(x * np.pi * 2 / 25, abs(y), width=0.3, alpha=0.3)

ax2 = fig.add_subplot(2, 1, 2)
x2 = np.arange(25)
y2 = np.sin(2 * np.pi * x2 / 25)
ax2.bar(x2, y2)
plt.show()

內容解密:

  1. add_subplot() 方法用於建立多個軸物件,並指定它們在網格中的位置。
  2. bar() 方法用於建立條形圖,可以透過 widthalpha 引數控制條形的寬度和透明度。
  3. 在極座標系統中,需要將 x 值轉換為弧度,並且要注意全圓範圍是從 0 到 2π。

使用文字字串

matplotlib 自動為軸新增值,但我們需要手動新增其他文字,如軸註解、圖形標題和各種標籤。Axes 物件提供了多個輔助函式來幫助我們新增文字。

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1,
                     title="四次多項式",
                     xlabel='X 軸',
                     ylabel='Y 軸')
x = np.linspace(-5., 3)
y = 0.2 * x**4 + 0.5 * x**3 - 2.5 * x**2 - 1.2 * x - 0.6
ax.plot(x, y)
ax.grid(True)
ax.text(-4.5, 6, r'$y = 0.2 x^4 + 0.4 x^3 - 2.5 x^2 - 1.2 x - 0.6$', fontsize=14)
ax.annotate('轉折點',
            xy=(1.8, -7),
            xytext=(-0.8, -12.6),
            arrowprops=dict(arrowstyle="->"))
plt.show()

內容解密:

  1. 使用 titlexlabelylabel 引數可以在建立 Axes 物件時設定標題和軸標籤。
  2. text() 方法允許在圖形上任意位置新增文字,需指定座標和文字字串。
  3. annotate() 方法用於建立註解,可以透過 xytextxy 引數控制註解文字的位置和箭頭指向。
  4. 使用 TeX 語法可以渲染數學公式,需將公式包圍在 $ 符號中。