返回文章列表

Pandas資料處理Excel與SQLAlchemy整合應用

本文介紹如何使用 pandas 讀取和處理 Excel 檔案,包含指定工作表、跳過列、選擇欄位等技巧,並探討階層式資料處理與 MultiIndex 建立。此外,文章也涵蓋了 pandas 與 SQL 資料函式庫的互動,特別是 SQLAlchemy 的應用,以及高效能的 ADBC 和 Parquet

資料科學 Python

Pandas 的 I/O 系統簡化了資料科學家處理不同來源資料的流程,尤其在面對 Excel 檔案和 SQL 資料函式庫時,更顯其強大功能。讀取 Excel 檔案時,pd.read_excel 函式的 sheet_nameskiprowsusecols 等引數提供了高度彈性,讓開發者能精準讀取所需資料。階層式資料的處理也是 pandas 的強項,透過 headerindex_col 引數,可以輕鬆建立 MultiIndex,有效管理複雜資料結構。此外,pandas 整合 SQLAlchemy,讓 Python 與各種 SQL 資料函式庫的互動更加便捷。對於追求極致效能的應用,ADBC 和 Parquet 則提供了更最佳化的解決方案。ADBC 作為新一代資料函式庫連線標準,專為列式資料函式庫設計,即使與傳統資料函式庫互動,也能展現優於 ODBC/JDBC 的效能。Parquet 則是一種高效的資料儲存格式,支援中繼資料儲存、分割儲存、查詢支援、平行處理和壓縮儲存等特性,大幅提升資料讀寫效率。

pandas I/O 系統:處理 Microsoft Excel 檔案

在資料分析中,經常需要處理來自不同來源的資料,其中 Microsoft Excel 檔案是非常常見的一種。pandas 提供了一個強大的 I/O 系統,能夠輕鬆讀取和寫入 Excel 檔案。

讀取 Excel 檔案

當讀取 Excel 檔案時,可能會遇到檔案格式不規範或資料未正確排列的情況。這時,可以使用 pd.read_excel 函式的各種引數來指定如何讀取資料。

指定工作表

預設情況下,pd.read_excel 會讀取 Excel 檔案中的第一個工作表。如果需要讀取其他工作表,可以使用 sheet_name 引數指定工作表的名稱或索引。

pd.read_excel(
    "data/beatles.xlsx",
    dtype_backend="numpy_nullable",
    sheet_name="the_data",
    skiprows=4,
    usecols="C:E",
)

跳過指定列

如果 Excel 檔案中的資料不是從第一行開始,可以使用 skiprows 引數跳過指定的列數。

選擇特定欄位

可以使用 usecols 引數選擇特定的欄位。可以透過指定欄位的字母範圍(如 “C:E”)或欄位的標籤列表(如 ["first", "last", "birth"])來選擇需要的欄位。

pd.read_excel(
    "data/beatles.xlsx",
    dtype_backend="numpy_nullable",
    sheet_name="the_data",
    skiprows=4,
    usecols=["first", "last", "birth"],
)

解讀程式碼

  • sheet_name="the_data" 指定要讀取的工作表名稱。
  • skiprows=4 跳過前 4 列。
  • usecols="C:E"usecols=["first", "last", "birth"] 選擇特定的欄位。

處理階層式資料

在資料分析中,經常需要處理階層式資料。pandas 可以輕鬆處理這種資料,並維持資料之間的階層關係。

建立 MultiIndex

可以使用 headerindex_col 引數建立 MultiIndex。

df = pd.read_excel(
    "data/hierarchical.xlsx",
    dtype_backend="numpy_nullable",
    index_col=[0, 1],
    header=[0, 1],
)

解讀程式碼

  • index_col=[0, 1] 指定前兩列為 row index。
  • header=[0, 1] 指定前兩行為 column index。

結果

Year        2024       2025      
Quarter      Q1   Q2   Q1    Q2
Region Sub-Region                
America East      1    2    4     8
        West     16   32   64   128
        South   256  512 1024  4096
Europe West    8192 16384 32768 65536
        East   131072 262144 524288 1048576

使用 SQLAlchemy 與 SQL 資料函式庫互動

pandas 提供了一個強大的功能,可以與 SQL 資料函式庫互動。這個功能是根據 SQLAlchemy 函式庫,可以連線到各種不同的 SQL 資料函式庫。

連線資料函式庫

要連線 SQL 資料函式庫,需要使用 SQLAlchemy 的 create_engine 方法建立一個引擎物件。

理論上,pandas 可以與任何 SQLAlchemy 可以連線的資料函式庫一起工作。

重點整理

  • 使用 pd.read_excel 可以讀取 Excel 檔案,並透過各種引數指定如何讀取資料。
  • 可以使用 sheet_nameskiprowsusecols 等引數控制讀取的資料。
  • pandas 可以處理階層式資料,並維持資料之間的階層關係。
  • 可以使用 headerindex_col 建立 MultiIndex。
  • pandas 可以與 SQL 資料函式庫互動,使用 SQLAlchemy 連線各種不同的 SQL 資料函式庫。

使用SQLAlchemy與ADBC進行資料函式庫操作

在進行資料函式庫操作時,pandas提供了多種方法來讀取和寫入資料。本文將介紹如何使用SQLAlchemy和ADBC來進行資料函式庫操作。

使用SQLAlchemy

首先,我們需要安裝SQLAlchemy。可以使用以下命令進行安裝:

python -m pip install sqlalchemy

SQLAlchemy支援多種資料函式庫,包括MySQL、PostgreSQL、MS SQL Server等。為了簡化操作,我們將使用SQLite作為範例資料函式庫。

建立SQLAlchemy引擎

首先,我們需要建立一個SQLAlchemy引擎。使用sa.create_engine函式可以建立一個引擎,函式的引數是一個URL字串。

import sqlalchemy as sa
engine = sa.create_engine("sqlite:///:memory:")

寫入資料到資料函式庫

使用pd.DataFrame.to_sql方法可以將一個DataFrame寫入到資料函式庫中。

import pandas as pd

df = pd.DataFrame([
    ["dog", 4],
    ["cat", 4],
], columns=["animal", "num_legs"])

df = df.convert_dtypes(dtype_backend="numpy_nullable")
df.to_sql("table_name", engine, index=False)

從資料函式庫讀取資料

使用pd.read_sql函式可以從資料函式庫中讀取資料。

pd.read_sql("table_name", engine, dtype_backend="numpy_nullable")

輸出結果:

  animal  num_legs
0     dog         4
1     cat         4

執行SQL查詢

使用pd.read_sql函式也可以執行SQL查詢。

pd.read_sql(
    "SELECT SUM(num_legs) AS total_legs FROM table_name",
    engine,
    dtype_backend="numpy_nullable"
)

輸出結果:

   total_legs
0           8

使用ADBC

ADBC(Arrow Database Connectivity)是Apache Arrow專案中的一個新技術,可以提供更好的效能和型別安全。

安裝ADBC驅動程式

首先,我們需要安裝ADBC驅動程式。可以使用以下命令進行安裝:

python -m pip install adbc-driver-sqlite

建立ADBC連線

使用dbapi.connect函式可以建立一個ADBC連線。

from adbc_driver_sqlite import dbapi

with dbapi.connect("file::memory:") as conn:
    # 進行資料函式庫操作
    pass

寫入資料到資料函式庫

使用pd.DataFrame.to_sql方法可以將一個DataFrame寫入到資料函式庫中。

df = pd.DataFrame([
    ["dog", 4],
    ["cat", 4],
    ["human", 2],
], columns=["animal", "num_legs"])

df = df.convert_dtypes(dtype_backend="numpy_nullable")

with dbapi.connect("file::memory:") as conn:
    df.to_sql("table_name", conn, index=False, if_exists="replace")
    df = pd.read_sql(
        "SELECT * FROM table_name",
        conn,
        dtype_backend="numpy_nullable",
    )

df

輸出結果:

  animal  num_legs
0     dog         4
1     cat         4
2   human         2

效能比較

使用ADBC可以提供更好的效能。下面是一個簡單的效能比較範例:

import timeit
import sqlalchemy as sa
import numpy as np

np.random.seed(42)
df = pd.DataFrame(
    np.random.randn(10_000, 10),
    columns=list("abcdefghij")
)

with sa.create_engine("sqlite:///:memory:").connect() as conn:
    func = lambda: df.to_sql("test_table", conn, if_exists="replace")
    print(timeit.timeit(func, number=100))

with dbapi.connect("file::memory:") as conn:
    func = lambda: df.to_sql("test_table", conn, if_exists="replace")
    print(timeit.timeit(func, number=100))

輸出結果:

4.898935955003253
0.7935214300014195

從結果可以看出,使用ADBC可以提供更好的效能。

內容解密:

此範例展示瞭如何使用SQLAlchemy和ADBC進行資料函式庫操作。SQLAlchemy是一個成熟的ORM工具,支援多種資料函式庫,而ADBC則是一個新的技術,可以提供更好的效能和型別安全。在選擇使用哪種技術時,需要根據具體的需求和資料函式庫型別進行考慮。

Plantuml資料函式庫操作流程

**圖表翻譯:**此圖表展示了資料函式庫操作的基本流程。首先,需要建立一個資料函式庫連線。然後,可以將資料寫入到資料函式庫中,或者從資料函式庫中讀取資料。同時,也可以執行SQL查詢來取得特定的資料。

內容解密:

此Plantuml圖表展示了資料函式庫操作的基本流程,包括建立資料函式庫連線、寫入資料、讀取資料和執行SQL查詢等步驟。透過這個流程圖,可以清晰地瞭解資料函式庫操作的基本步驟和邏輯關係。

資料儲存與讀取的最佳實踐:Apache Parquet 與 ADBC 的優勢

在資料分析和處理的過程中,選擇適當的資料儲存格式和資料函式庫互動方式至關重要。Apache Parquet 和 ADBC(Arrow Database Connectivity)是兩個重要的技術,它們分別解決了資料儲存和資料函式庫互動的問題。

為何需要標準化的資料函式庫連線?

在 1990 年代,Open Database Connectivity(ODBC)和 Java Database Connectivity(JDBC)標準的出現,簡化了不同客戶端與各種資料函式庫之間的互動。在此之前,應用程式需要為每個資料函式庫編寫特定的程式碼,以實作與資料函式庫的互動。例如,若要取得資料函式庫中的表格列表,PostgreSQL 資料函式庫需要查詢 pg_catalog.pg_tables 表格,而 SQLite 資料函式庫則需要查詢 sqlite_schema 表格。ODBC 和 JDBC 的出現,將資料函式庫互動的複雜性轉移到了驅動程式身上,使得應用程式可以與不同的資料函式庫進行互動,而無需修改應用程式本身。

ADBC:為列式資料函式庫而生的標準

雖然 ODBC 和 JDBC 標準在當時解決了許多問題,但它們主要是針對行式資料函式庫設計的。隨著列式資料函式庫的興起,例如 BigQuery、Redshift 和 Snowflake,ADBC 應運而生。ADBC 是一種列式資料函式庫連線標準,它使得 pandas 等列式資料處理函式庫可以高效地與列式資料函式庫進行互動。ADBC 驅動程式針對 Apache Arrow 進行了最佳化,因此即使不使用列式資料函式庫,也能提供比 ODBC/JDBC 更好的效能。

Apache Parquet:高效的資料儲存格式

Apache Parquet 是一種高效的資料儲存格式,適用於儲存 pd.DataFrame。它提供了多項優勢,包括:

  • 中繼資料儲存:Parquet 檔案可以儲存資料型別等中繼資料。
  • 分割儲存:資料可以分割成多個檔案儲存。
  • 查詢支援:Parquet 檔案可以被查詢,而無需將所有資料載入記憶體。
  • 平行處理:讀取 Parquet 檔案可以平行處理,以提高效率。
  • 壓縮儲存:Parquet 檔案採用壓縮儲存,節省儲存空間。

使用 Apache Parquet 儲存和讀取資料

pandas 提供了 pd.read_parquetpd.DataFrame.to_parquet 方法,分別用於讀取和寫入 Parquet 檔案。以下是一個範例:

import io
import pandas as pd

# 建立範例資料
df = pd.DataFrame([
    ["Paul", "McCartney", 1942],
    ["John", "Lennon", 1940],
    ["Richard", "Starkey", 1940],
    ["George", "Harrison", 1943],
], columns=["first", "last", "birth"])

# 將資料轉換為適當的資料型別
df = df.convert_dtypes(dtype_backend="numpy_nullable")

# 將 DataFrame 寫入 Parquet 檔案
buf = io.BytesIO()
df.to_parquet(buf, index=False)

# 將檔案指標移回檔案起始位置
buf.seek(0)

# 從 Parquet 檔案讀取 DataFrame
read_df = pd.read_parquet(buf)

print(read_df)

#### 內容解密:

在這個範例中,我們首先建立了一個包含 Beatles 成員資訊的 DataFrame。然後,我們將 DataFrame 寫入了一個 io.BytesIO 物件中,使用 to_parquet 方法。接著,我們將檔案指標移回檔案起始位置,並使用 read_parquet 方法從 io.BytesIO 物件中讀取 DataFrame。可以觀察到,讀取出來的 DataFrame 與原始 DataFrame 相同。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Pandas資料處理Excel與SQLAlchemy整合應用

package "資料庫架構" {
    package "應用層" {
        component [連線池] as pool
        component [ORM 框架] as orm
    }

    package "資料庫引擎" {
        component [查詢解析器] as parser
        component [優化器] as optimizer
        component [執行引擎] as executor
    }

    package "儲存層" {
        database [主資料庫] as master
        database [讀取副本] as replica
        database [快取層] as cache
    }
}

pool --> orm : 管理連線
orm --> parser : SQL 查詢
parser --> optimizer : 解析樹
optimizer --> executor : 執行計畫
executor --> master : 寫入操作
executor --> replica : 讀取操作
cache --> executor : 快取命中

master --> replica : 資料同步

note right of cache
  Redis/Memcached
  減少資料庫負載
end note

@enduml

圖表翻譯: 此圖表展示了使用 Apache Parquet 儲存和讀取 DataFrame 的過程。首先,建立一個 DataFrame,然後將其寫入 Parquet 檔案。接著,從 Parquet 檔案中讀取 DataFrame,並取得最終的 DataFrame。

使用 Apache Parquet 和 ADBC,可以簡化資料儲存和資料函式庫互動的過程,提高資料處理的效率和效能。這些技術在現代資料分析和處理中扮演著重要的角色。