使用 Parquet 檔案

使用 Polars 擴充與最佳化資料管線

Liam Brannigan

Data Scientist & Polars Contributor

檔案儲存格式

DataFrame 示意圖

使用 Polars 擴充與最佳化資料管線

CSV 格式

圖示說明 CSV 為逐列儲存,每筆紀錄橫跨整列。

使用 Polars 擴充與最佳化資料管線

Parquet 格式

圖示說明 Parquet 為欄式儲存,同欄位的值被分組在一起。

使用 Polars 擴充與最佳化資料管線

轉換封存檔

(
    pl.read_csv("311_Service_Requests.csv", try_parse_dates=True)

)
使用 Polars 擴充與最佳化資料管線

轉換封存檔

(
    pl.read_csv("311_Service_Requests.csv", try_parse_dates=True)
    .write_parquet("311_Service_Requests.parquet")
)
使用 Polars 擴充與最佳化資料管線

檢視 Parquet 檔

pl.read_parquet_schema(
    "311_Service_Requests.parquet"
)
Schema(
    "CREATED_DATE": Datetime,
    "TYPE": String,
    "STATUS": String,
    "DEPARTMENT": String,
    "WARD": Int64,
    ...
)
使用 Polars 擴充與最佳化資料管線

CSV vs Parquet

$$

CSV
  • 4.8 GB
  • 14 秒

$$

Parquet
  • 0.6 GB
  • 1.4 秒

csv 與 parquet 比較示意圖

使用 Polars 擴充與最佳化資料管線

Parquet 不適合追加列

new_request = {"TYPE": "Pothole", "STATUS": "Open", ...}
  • 追加用 CSV
  • 讀取用 Parquet
使用 Polars 擴充與最佳化資料管線

Parquet 列群組

顯示 Parquet 檔分成列群組的圖。

使用 Polars 擴充與最佳化資料管線

用列群組過濾

(
    pl.scan_parquet("311_Service_Requests.parquet")
    .filter(pl.col("CREATED_DATE") < pl.datetime(2020, 1, 1))
)
使用 Polars 擴充與最佳化資料管線

Parquet 列群組

含列群組的 Parquet 檔示意圖。

使用 Polars 擴充與最佳化資料管線

Parquet 列群組

含列群組與統計資訊的 Parquet 檔示意圖。

使用 Polars 擴充與最佳化資料管線

使用平行策略掃描

(
    pl.scan_parquet(
        "311_Service_Requests.parquet",

    )
)
使用 Polars 擴充與最佳化資料管線

使用平行策略掃描

(
    pl.scan_parquet(
        "311_Service_Requests.parquet",
        parallel="row_groups",
    )
)
  • columns
  • prefiltered
  • none
使用 Polars 擴充與最佳化資料管線

控制 Parquet 寫入

department_counts.write_parquet(
    "department_counts.parquet",
    compression_level=3,

)
  • 檔案更小
  • 讀寫時間更長
使用 Polars 擴充與最佳化資料管線

控制 Parquet 寫入

department_counts.write_parquet(
    "department_counts.parquet",
    compression_level=3,
    row_group_size=25_000,
)
  • 檔案更小
  • 讀寫時間更長
  • 可讀取更多統計
使用 Polars 擴充與最佳化資料管線

一起來練習吧!

使用 Polars 擴充與最佳化資料管線

Preparing Video For Download...