在資料分析領域,有效地理解和運用資料視覺化技術至關重要。本文將深入探討如何利用 Python 的 Pandas 和 Matplotlib 函式庫來探索分類別資料的分佈特性。文章以實際的車輛資料集為例,詳細說明瞭如何識別、清理和視覺化分類別資料,並使用散佈圖、柱狀圖等技術展現資料分佈。此外,本文也涵蓋了連續資料的探索與視覺化方法,例如直方圖和 KDE 圖,以及缺失值的處理技巧,提供讀者更全面的資料探索與視覺化。

資料視覺化:分類別資料的探索

在資料分析的過程中,視覺化是一種強大的工具,可以幫助我們快速理解資料的特性與趨勢。本章節將重點探討如何使用視覺化技術來探索分類別資料(Categorical Data)的分佈特性。

分類別資料的定義

分類別資料是指那些用於分類別或導航資料的值,但這些值本身不適合進行數學運算。例如,在一個包含個人資料的資料集中,「眼睛顏色」這一欄位就是一個典型的分類別資料。我們可以根據眼睛顏色來篩選資料,但無法對這些顏色進行加總或平均等數學運算。

連續資料與分類別資料的區別

與分類別資料相對的是連續資料(Continuous Data)。連續資料是指那些可以進行數學運算的資料,例如身高、體重、年齡等。這些資料可以被匯總、平均或進行其他數學運算。

散佈圖矩陣(Scatter Matrix)

散佈圖矩陣是一種用於視覺化多個連續變數之間關係的強大工具。它可以一次性展示資料集中所有連續欄位之間的兩兩關係。讓我們使用前述的車輛資料集來展示散佈圖矩陣的應用:

from pandas.plotting import scatter_matrix
scatter_matrix(df)

圖表翻譯:

此圖示展示了車輛資料集中各個連續變數之間的關係。每一列代表一個變數作為Y軸,每一行代表一個變數作為X軸。對角線上的圖表展示了單一變數的分佈情況,而非對角線上的圖表則展示了兩個變數之間的散佈關係。

探索分類別資料

在本章節中,我們將學習如何使用視覺化技術來探索分類別資料的分佈特性。我們將使用車輛資料集中的「VClass」欄位作為範例,這是一個典型的分類別變數。

首先,我們需要確保「VClass」欄位被正確地識別為分類別資料型別:

car_classes = ("Subcompact Cars", "Compact Cars", "Midsize Cars", "Large Cars", "Two Seaters")
cat = pd.CategoricalDtype(car_classes)
df["VClass"] = df["VClass"].astype(cat)

接下來,我們可以使用散佈圖來展示不同車輛類別之間的關係,並使用顏色來區分不同的類別:

df.plot(kind="scatter", x="city08", y="highway08", c="VClass", colormap="Dark2")

圖表翻譯:

此圖示展示了不同車輛類別在城市油耗(city08)和高速公路油耗(highway08)之間的關係。不同的顏色代表不同的車輛類別。從圖中可以觀察到,不同類別的車輛在油耗表現上存在一定的差異。

資料視覺化的進階應用

除了基本的散佈圖外,我們還可以透過調整資料點的大小來展示更多的資訊。例如,我們可以使用「fuelCost08」欄位來代表資料點的大小:

df.assign(scaled_fuel_cost=lambda x: x["fuelCost08"] / 25).plot(
    kind="scatter", 
    x="city08", 
    y="highway08", 
    c="VClass", 
    colormap="Dark2", 
    s="scaled_fuel_cost", 
    alpha=0.4
)

圖表翻譯:

此圖示展示了不同車輛類別的油耗表現與年度燃料成本之間的關係。資料點的大小代表了年度燃料成本的高低。從圖中可以觀察到,油耗較差的車輛通常具有較高的年度燃料成本。

在未來的分析中,我們可以進一步探索其他型別的視覺化技術,例如條形圖、直方圖等,以更全面地理解資料的特性。同時,我們也可以結合機器學習演算法,對分類別資料進行更深入的分析和預測。

Mermaid 圖表示例

  flowchart TD
    A[開始] --> B{資料型別檢查}
    B -->|分類別資料| C[使用條形圖視覺化]
    B -->|連續資料| D[使用散佈圖視覺化]
    C --> E[分析分類別資料分佈]
    D --> F[分析變數間關係]
    E --> G[結論]
    F --> G

圖表翻譯:

此圖示展示了根據資料型別選擇適當視覺化方法的流程。首先檢查資料型別,如果是分類別資料,則使用條形圖進行視覺化;如果是連續資料,則使用散佈圖。接著根據視覺化結果進行相應的分析,最終得出結論。這個流程圖幫助分析師根據資料特性選擇最合適的視覺化策略。

資料載入與初步檢視

在進行資料分析時,首先需要載入資料並進行初步檢視。以下程式碼展示瞭如何使用 pandas 讀取 CSV 檔案並檢視資料的基本資訊。

import pandas as pd

# 讀取 CSV 檔案
df = pd.read_csv("data/vehicles.csv.zip", dtype_backend="numpy_nullable")

# 檢視資料前幾行
print(df.head())

程式碼解析:

  1. 載入必要的函式庫:首先匯入 pandas 函式庫,用於資料處理。
  2. 讀取 CSV 檔案:使用 pd.read_csv 函式讀取壓縮的 CSV 檔案。指定 dtype_backend="numpy_nullable" 以最佳化資料型別。
  3. 檢視資料前幾行:使用 df.head() 函式檢視資料的前幾行,以瞭解資料的基本結構。

處理混合資料型別的欄位

在讀取資料時,可能會遇到某些欄位具有混合資料型別的情況。以下程式碼展示瞭如何處理這些欄位。

# 檢視具有混合資料型別的欄位
print(df.iloc[:, [72, 74, 75, 77]].head())

# 檢視特定欄位的數值分佈
print(df["rangeA"].value_counts())

# 找出第一個非數值資料的位置
print(df["rangeA"].str.isnumeric().idxmax())

程式碼解析:

  1. 檢視混合資料型別欄位:使用 df.iloc 選取特定的欄位,並檢視其內容。
  2. 檢視特定欄位的數值分佈:使用 value_counts() 函式檢視欄位中的數值分佈情況。
  3. 找出第一個非數值資料的位置:使用 str.isnumeric().idxmax() 找出第一個非數值的資料位置。

資料清理與型別指定

為了避免 pandas 在讀取資料時發出型別推斷警告,我們可以明確指定某些欄位的資料型別。

# 明確指定某些欄位的資料型別
df = pd.read_csv(
 "data/vehicles.csv.zip",
 dtype_backend="numpy_nullable",
 dtype={
 "rangeA": pd.StringDtype(),
 "mfrCode": pd.StringDtype(),
 "c240Dscr": pd.StringDtype(),
 "c240bDscr": pd.StringDtype()
 }
)

# 再次檢視資料前幾行
print(df.head())

程式碼解析:

  1. 明確指定欄位型別:在讀取 CSV 檔案時,使用 dtype 引數明確指定某些欄位的資料型別為字串型別。
  2. 再次檢視資料:使用 df.head() 再次檢視資料,以確認資料型別的指定是否成功。

識別類別型欄位

在資料分析中,識別類別型欄位是非常重要的一步。以下程式碼展示瞭如何識別這些欄位。

# 選取資料型別為字串的欄位
categorical_columns = df.select_dtypes(include=["string"]).columns
print(categorical_columns)

# 計算每個類別型欄位的唯一值數量
unique_counts = df.select_dtypes(include=["string"]).nunique().sort_values()
print(unique_counts)

程式碼解析:

  1. 選取字串型別欄位:使用 select_dtypes 函式選取資料型別為字串的欄位,這些欄位可能是類別型資料。
  2. 計算唯一值數量:使用 nunique() 函式計算每個類別型欄位的唯一值數量,並進行排序。

資料視覺化

為了更好地理解資料,我們可以對類別型欄位進行視覺化。以下程式碼展示瞭如何繪製柱狀圖。

# 選取基數較低的欄位進行視覺化
low_card = df.select_dtypes(include=["string"]).nunique().sort_values().iloc[:9].index

# 建立 3x3 的子圖網格
fig, axes = plt.subplots(nrows=3, ncols=3)

# 對每個選定的欄位繪製柱狀圖
for index, column in enumerate(low_card):
 row = index % 3
 col = index // 3
 ax = axes[row][col]
 counts = df[column].value_counts()
 counts.set_axis(counts.index.str[:8]).plot(kind="bar", ax=ax)
 ax.set_xticklabels(ax.get_xticklabels(), rotation=45, fontsize=6)

# 調整佈局
plt.tight_layout()

程式碼解析:

  1. 選取基數較低的欄位:選擇唯一值數量較少的欄位進行視覺化。
  2. 建立子圖網格:使用 plt.subplots 建立一個 3x3 的子圖網格,以便於同時展示多個欄位的分佈情況。
  3. 繪製柱狀圖:對每個選定的欄位,使用 value_counts() 統計數值分佈,並繪製柱狀圖。
  4. 調整 X 軸標籤:縮短 X 軸標籤的長度,並進行旋轉和字型大小的調整,以提高可讀性。

Mermaid 圖表:資料處理流程

  flowchart TD
 A[開始] --> B[載入資料]
 B --> C[檢視資料基本資訊]
 C --> D[處理混合資料型別欄位]
 D --> E[指定資料型別]
 E --> F[識別類別型欄位]
 F --> G[視覺化類別型欄位]
 G --> H[結束]

圖表解析:

此圖表展示了資料處理的流程,從載入資料開始,逐步進行資料檢視、處理混合資料型別欄位、指定資料型別、識別類別型欄位,最後進行視覺化。這個流程幫助我們系統地理解和清理資料,為後續的分析做好準備。

連續資料的視覺化與探索

在前面的章節中,我們探討了分類別資料的探索方法。本章節將重點轉移到連續資料的探索與視覺化,使用相同的 vehicles 資料集。該資料集包含了豐富的連續資料欄位,使其成為一個理想的範例。

資料載入與初步檢視

首先,我們載入所需的資料集,並對其進行初步檢視。以下程式碼展示瞭如何使用 pandas 讀取 vehicles.csv.zip 檔案:

import pandas as pd
import matplotlib.pyplot as plt

# 載入資料集
df = pd.read_csv(
    "data/vehicles.csv.zip",
    dtype_backend="numpy_nullable",
    dtype={
        "rangeA": pd.StringDtype(),
        "mfrCode": pd.StringDtype(),
        "c240Dscr": pd.StringDtype(),
        "c240bDscr": pd.StringDtype()
    }
)

# 檢視資料集的前幾行
print(df.head())

程式碼解析:

此段程式碼首先匯入必要的函式庫,包括 pandasmatplotlib.pyplot。接著,使用 pd.read_csv 函式讀取壓縮的 CSV 檔案。在讀取過程中,指定了資料型別處理方式,以確保欄位資料型別的正確性。最後,輸出資料集的前幾行以進行初步檢視。

連續資料的選取

為了專注於連續資料,我們使用 select_dtypes 方法排除字串型別的欄位,只保留數值型欄位:

# 選取連續資料欄位
continuous_columns = df.select_dtypes(exclude=["string"]).columns
print(continuous_columns)

程式碼解析:

這段程式碼利用 select_dtypes 方法,透過 exclude 引數排除字串型別的欄位,從而選取連續資料欄位。選取的結果儲存在 continuous_columns 變數中,並輸出這些欄位的名稱。

缺失值處理

在進行資料分析之前,檢查缺失值是必要的步驟。以下程式碼用於檢視各連續資料欄位的缺失值數量:

# 檢視連續資料欄位的缺失值數量
missing_values_count = df.select_dtypes(exclude=["string"]).pipe(pd.isna).sum().sort_values(ascending=False).head()
print(missing_values_count)

程式碼解析:

這段程式碼首先選取連續資料欄位,接著使用 pd.isna 方法識別缺失值,並計算每個欄位的缺失值數量。結果按降序排列,並輸出前幾個缺失值最多的欄位。

進一步檢視 cylindersdispl 欄位的缺失值情況:

# 檢視 cylinders 欄位缺失值的車輛品牌與型號
print(df.loc[df["cylinders"].isna(), ["make", "model"]].value_counts())

# 檢視 displ 欄位缺失值的車輛品牌與型號
print(df.loc[df["displ"].isna(), ["make", "model"]].value_counts())

程式碼解析:

這段程式碼分別檢視了 cylindersdispl 欄位缺失值對應的車輛品牌與型號。結果顯示,這些缺失值主要對應於電動車輛。因此,對於 cylinders 欄位,可以合理地將缺失值填補為 0。然而,對於 displ 欄位,填補缺失值為 0 可能會影響平均值的計算,因此選擇保留缺失值。

直方圖與密度圖視覺化

為了更好地理解連續資料的分佈情況,我們可以使用直方圖和核密度估計(KDE)圖進行視覺化。首先,繪製 city08 欄位的直方圖:

# 繪製 city08 欄位的直方圖
df["city08"].plot(kind="hist", bins=30)
plt.show()

程式碼解析:

這段程式碼使用 plot 方法繪製 city08 欄位的直方圖,並設定 bins=30 以增加直方圖的細節。結果顯示,該欄位資料呈現出一定的偏態分佈。

接下來,使用 KDE 圖進一步視覺化 city08highway08 欄位的分佈情況:

# 繪製 city08 和 highway08 欄位的 KDE 圖
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(8, 6))
axes[0].set_xlim(0, 40)
axes[1].set_xlim(0, 40)
axes[0].set_ylabel("city")
axes[1].set_ylabel("highway")
df["city08"].plot(kind="kde", ax=axes[0])
df["highway08"].plot(kind="kde", ax=axes[1])
plt.show()

程式碼解析:

這段程式碼使用 plt.subplots 方法建立兩個子圖,分別繪製 city08highway08 欄位的 KDE 圖。結果顯示,city08 欄位在 16-17 mpg 附近達到峰值,而 highway08 欄位在 23-24 mpg 附近達到峰值。

Mermaid 圖表視覺化流程

以下 Mermaid 圖表展示了連續資料探索與視覺化的流程:

  flowchart TD
 A[載入資料] --> B[選取連續資料欄位]
 B --> C[檢查缺失值]
 C --> D[處理缺失值]
 D --> E[繪製直方圖]
 E --> F[繪製 KDE 圖]
 F --> G[分析結果]

圖表翻譯:

此圖表展示了連續資料探索與視覺化的完整流程。首先,載入資料集並選取連續資料欄位。接著,檢查並處理缺失值。然後,分別繪製直方圖和 KDE 圖以視覺化資料分佈。最後,根據視覺化結果進行分析與解讀。