Pandas 是 Python 資料分析的核心函式庫,提供豐富的資料操作工具。本文聚焦於聚合、轉換和對映三種關鍵技術,並結合程式碼範例,解析如何在不同資料結構上應用這些方法。同時也介紹了資料分箱的技巧,包含使用 pd.cut 進行分組和 pd.get_dummies 進行獨熱編碼,最後以流程圖形式總結了資料處理的完整步驟,方便讀者快速掌握 Pandas 資料處理的核心概念和實務操作。

Pandas 資料分析中的聚合、轉換與對映技術

在進行資料分析時,Pandas 函式庫提供了多種強大的工具來處理和轉換資料。本文將深入探討聚合(Aggregation)、轉換(Transformation)和對映(Mapping)這三種重要技術,並透過具體範例展示如何在實際資料分析中應用這些方法。

聚合操作

聚合操作是指將多個資料值合併成一個單一值的過程。在 Pandas 中,無論是 Series 還是 DataFrame,都支援多種聚合操作。

Series 聚合

對於 Series 而言,聚合操作相對簡單,因為只有一個維度需要考慮。我們可以直接呼叫如 summean 等方法來進行聚合。

import pandas as pd
import numpy as np

# 建立一個包含隨機數的 Series
np.random.seed(42)
ser = pd.Series(np.random.rand(10_000), dtype=pd.Float64Dtype())

# 計算平均值並加上 42
def mean_and_add_42(ser: pd.Series):
    return ser.mean() + 42

# 使用 agg 方法進行聚合
result = ser.agg(mean_and_add_42)
print(result)

DataFrame 聚合

對於 DataFrame,聚合操作可以沿著不同的軸(axis)進行。預設情況下,聚合操作沿著列(axis=0)進行。

# 建立一個包含隨機數的 DataFrame
np.random.seed(42)
df = pd.DataFrame(np.random.randn(10_000, 6), columns=list("abcdef")).convert_dtypes(dtype_backend="numpy_nullable")

# 沿著列進行求和聚合
result_columns = df.sum()
print(result_columns)

# 沿著行進行求和聚合
result_rows = df.sum(axis=1)
print(result_rows)

同時進行多重聚合

使用 agg 方法,我們可以同時對資料進行多種聚合操作。

# 同時計算最小值和最大值
result = df.agg(["min", "max"])
print(result)

轉換操作

轉換操作與聚合操作不同,它們不會減少資料的維度,而是保持原始資料的形狀。

Series 轉換

對於 Series,我們可以使用 transform 方法來進行轉換操作。

# 建立一個簡單的 Series
ser = pd.Series([-1, 0, 1], dtype=pd.Int64Dtype())

# 定義一個轉換函式
def adds_one(ser: pd.Series) -> pd.Series:
    return ser + 1

# 進行轉換操作
result = ser.transform(["abs", adds_one])
print(result)

DataFrame 轉換

同樣地,DataFrame 也可以使用 transform 方法進行轉換。

# 建立一個 DataFrame
df = pd.DataFrame(np.arange(-5, 4, 1).reshape(3, -1)).convert_dtypes(dtype_backend="numpy_nullable")

# 進行絕對值轉換
result_abs = df.transform("abs")
print(result_abs)

# 同時進行多種轉換
def add_42(ser: pd.Series):
    return ser + 42

result_multiple = df.transform(["abs", add_42])
print(result_multiple)

對映操作

對映操作允許我們對資料中的每個元素單獨進行處理,這在處理混合型資料時特別有用。

對 Series 進行對映

# 建立一個混合型別的 Series
ser = pd.Series([123.45, [100, 113], 142.0, [110, 113, 119]])

# 定義一個自定義平均函式
def custom_average(value):
    if isinstance(value, list):
        return sum(value) / len(value)
    return value

# 對 Series 中的每個元素進行對映
result = ser.map(custom_average)
print(result)

對 DataFrame 進行對映

同樣地,我們也可以對 DataFrame 中的每個元素進行對映。

# 建立一個混合型別的 DataFrame
df = pd.DataFrame([
    [2., [1, 2], 3.],
    [[4, 5], 5, 7.],
    [1, 4, [1, 1, 5.5]],
])

# 對 DataFrame 中的每個元素進行對映
result = df.map(custom_average)
print(result)

視覺化流程圖

以下是一個簡單的流程圖,用於展示資料處理的基本步驟:

  flowchart TD
    A[開始] --> B{檢查資料型別}
    B -->|數值型別| C[進行聚合操作]
    B -->|混合型別| D[進行對映操作]
    C --> E[結果輸出]
    D --> E

圖表翻譯:

此圖示展示了資料處理的基本流程。首先檢查資料的型別,如果是數值型別,則進行聚合操作;如果是混合型別,則進行對映操作。最後輸出處理結果。

資料分析中的分組與摘要統計

在資料分析過程中,經常需要對資料進行分組或計算摘要統計,以理解資料的基本特性和分佈情況。本章節將介紹 pandas 中幾個強大的方法,包括 pd.Series.value_countspd.Series.describepd.cut,這些方法能夠幫助分析師快速掌握資料的關鍵特徵。

摘要統計

摘要統計提供了一種快速瞭解資料基本屬性和分佈的方式。pandas 中的 pd.Series.value_countspd.Series.describe 方法是進行資料探索的強大工具。

使用 pd.Series.value_counts

pd.Series.value_counts 方法能夠計算每個不同資料點的頻率,對於離散型資料尤其有用。

# 建立一個包含字串的 Series
ser = pd.Series(["a", "b", "c", "a", "c", "a"], dtype=pd.StringDtype())

# 計算每個值的出現次數
ser.value_counts()

圖表說明:value_counts 流程

  flowchart TD
 A[建立 Series] --> B{計算值次數}
 B --> C[輸出結果]

圖表翻譯:

此圖示展示了使用 value_counts 方法計算 Series 中各個值出現次數的流程。首先建立一個包含資料的 Series,然後呼叫 value_counts 方法,最後輸出結果。

使用 pd.Series.describe

對於連續型資料,pd.Series.describe 方法提供了一系列統計指標,包括計數、平均值、最小值和最大值等,能夠給出資料分佈的整體概覽。

# 建立一個包含整數的 Series
ser = pd.Series([0, 42, 84], dtype=pd.Int64Dtype())

# 計算並輸出描述性統計
ser.describe()

圖表說明:describe 流程

  flowchart TD
 A[建立 Series] --> B{計算描述性統計}
 B --> C[輸出結果]

圖表翻譯:

此圖示展示了使用 describe 方法計算 Series 描述性統計的流程。首先建立一個包含資料的 Series,然後呼叫 describe 方法,最後輸出結果。

分箱演算法

分箱是將連續變數分類別到離散區間的過程,可以將無限多的值轉換為有限的「箱」以便於分析。

使用 pd.cut 進行分箱

假設我們有一份包含使用者年齡的調查資料,可以使用 pd.cut 將這些年齡分組到不同的年齡段。

# 建立一個包含使用者名稱和年齡的 DataFrame
df = pd.DataFrame([
 ["Jane", 34],
 ["John", 18],
 ["Jamie", 22],
 ["Jessica", 36],
 ["Jackie", 33],
 ["Steve", 40],
 ["Sam", 30],
 ["Stephanie", 66],
 ["Sarah", 55],
 ["Aaron", 22],
 ["Erin", 28],
 ["Elsa", 37],
], columns=["name", "age"])

# 將年齡分成 4 組
pd.cut(df["age"], 4)

圖表說明:pd.cut 分箱流程

  flowchart TD
 A[建立 DataFrame] --> B{將年齡分組}
 B --> C[輸出分組結果]

圖表翻譯:

此圖示展示了使用 pd.cut 方法將年齡資料分箱的流程。首先建立一個包含使用者資料的 DataFrame,然後呼叫 pd.cut 方法將年齡分成指定數量的組別,最後輸出分組結果。

資料轉換方法:maptransformapply

在資料處理過程中,經常需要對資料進行轉換。pandas 提供了多種方法,如 maptransformapply,用於不同的資料轉換需求。

map 方法

map 方法能夠對 Series 中的每個元素應用一個函式。

# 定義一個自定義平均值函式
def custom_average(value):
 if isinstance(value, list):
 return sum(value) / len(value)
 return value

# 建立一個 Series 並應用自定義函式
ser = pd.Series([[1, 2], 3, [4, 5]])
ser.map(custom_average)

圖表說明:map 方法流程

  flowchart TD
 A[建立 Series] --> B{應用自定義函式}
 B --> C[輸出結果]

圖表翻譯:

此圖示展示了使用 map 方法對 Series 中的每個元素應用自定義函式的流程。首先建立一個包含資料的 Series,然後呼叫 map 方法應用函式,最後輸出結果。

transform 方法

transform 方法與 map 類別似,但它適用於 DataFrame 時會對每一列進行操作。

# 對 DataFrame 的每一列應用自定義函式
df = pd.DataFrame({
 'A': [1, 2, 3],
 'B': [[4, 5], 6, 7]
})
df.transform(custom_average)

圖表說明:transform 方法流程

  flowchart TD
 A[建立 DataFrame] --> B{對每一列應用函式}
 B --> C[輸出結果]

圖表翻譯:

此圖示展示了使用 transform 方法對 DataFrame 的每一列應用自定義函式的流程。首先建立一個包含資料的 DataFrame,然後呼叫 transform 方法應用函式,最後輸出結果。

apply 方法

apply 方法提供了更大的靈活性,可以對 Series 或 DataFrame 的元素或列應用函式。

# 對 Series 的每個元素應用除錯函式
def debug_apply(value):
 print(f"Apply was called with value:\n{value}")
 return value

ser = pd.Series([0, 1, 2], dtype=pd.Int64Dtype())
ser.apply(debug_apply)

圖表說明:apply 方法流程

  flowchart TD
 A[建立 Series] --> B{對每個元素應用除錯函式}
 B --> C[輸出結果]

圖表翻譯:

此圖示展示了使用 apply 方法對 Series 的每個元素應用除錯函式的流程。首先建立一個包含資料的 Series,然後呼叫 apply 方法應用函式,最後輸出結果。

資料分箱技術詳解

在資料分析和機器學習領域中,資料分箱(Binning)是一種常見的資料預處理技術,用於將連續型資料轉換為離散型資料。本章節將深入探討使用pandas函式庫中的pd.cut函式來實作資料分箱的方法。

使用pd.cut進行資料分箱

pd.cut函式的主要功能是根據指定的區間範圍,將連續型資料切割成不同的類別。以下是一個簡單的範例:

import pandas as pd

# 建立範例資料
data = {'name': ['Jane', 'John', 'Jamie', 'Jessica', 'Jackie', 'Steve', 'Sam', 'Stephanie', 'Sarah', 'Aaron', 'Erin', 'Elsa'],
        'age': [34, 18, 22, 36, 33, 40, 30, 66, 55, 22, 28, 37]}
df = pd.DataFrame(data)

# 使用pd.cut進行資料分箱
df['age_bin'] = pd.cut(df['age'], 4, precision=0)

print(df)

程式碼解析:

  1. 首先,我們建立了一個包含姓名和年齡的DataFrame。
  2. 使用pd.cut函式將年齡欄位分成4個區間。
  3. precision=0引數用於控制區間標籤的精確度,避免出現不必要的十進位數字。

自定義分箱區間

除了自動分箱外,pd.cut還允許我們自定義分箱區間。以下是一個範例:

# 自定義分箱區間
bins = [10, 20, 30, 40, 50, 60, 999]
labels = ['10-20', '20-30', '30-40', '40-50', '50-60', '60+']

df['age_group'] = pd.cut(df['age'], bins=bins, labels=labels, right=False)

print(df)

程式碼解析:

  1. 定義了自定義的分箱區間bins和對應的標籤labels
  2. 使用right=False引數控制區間的包含性,實作左閉右開的區間劃分。
  3. 將自定義的分箱結果儲存在新的age_group欄位中。

獨熱編碼(One-Hot Encoding)

在資料分析和機器學習中,常常需要將類別型資料轉換為數值型資料。pd.get_dummies函式提供了一種簡單的獨熱編碼方法。

# 建立範例Series
ser = pd.Series(["green", "brown", "blue", "amber", "hazel", "amber", "green", "blue", "green"], name="eye_colors", dtype=pd.StringDtype())

# 進行獨熱編碼
dummies = pd.get_dummies(ser, prefix='is')

print(dummies)

程式碼解析:

  1. 建立了一個包含類別型資料的Series。
  2. 使用pd.get_dummies函式進行獨熱編碼。
  3. prefix='is'引數用於自定義產生的欄位名稱字首。

資料處理流程最佳化

在進行資料處理時,合理的程式碼組織方式非常重要。pandas提供了.pipe方法來實作方法鏈式呼叫,使程式碼更加簡潔和可讀。

# 使用.pipe方法進行鏈式呼叫
result = (df
          .assign(age_bin=lambda x: pd.cut(x['age'], 4))
          .pipe(lambda x: pd.get_dummies(x, columns=['age_bin'])))

print(result)

程式碼解析:

  1. 使用.assign方法新增了一個age_bin欄位。
  2. 使用.pipe方法將DataFrame傳遞給pd.get_dummies函式進行獨熱編碼。
  3. 整個處理流程透過方法鏈的方式實作,提高了程式碼的可讀性。

Mermaid流程圖展示資料處理流程

  flowchart TD
    A[原始資料] --> B{資料預處理}
    B -->|連續型資料| C[使用pd.cut進行分箱]
    B -->|類別型資料| D[使用pd.get_dummies進行獨熱編碼]
    C --> E[資料分箱結果]
    D --> F[獨熱編碼結果]
    E --> G[最終資料集]
    F --> G

圖表解析:

此圖展示了資料處理的基本流程。首先,原始資料經過預處理階段。對於連續型資料,使用pd.cut進行分箱處理;對於類別型資料,則使用pd.get_dummies進行獨熱編碼。最終,處理後的資料被整合到最終的資料集中。這個流程清晰地展示了資料從原始狀態到可用狀態的轉換過程。