Polars 作為新興的資料處理函式庫,以其優異的效能和簡潔的語法著稱,逐漸受到資料科學社群的關注。本文旨在提供一個全面的 Polars 使用,從基礎概念到進階技巧,幫助讀者快速掌握 Polars 的核心功能。首先,我們會介紹 Polars 的基本資料結構 Series 和 DataFrame,並示範如何建立、操作和分析這些資料結構。接著,我們將深入探討 Polars 的 Lazy API,這是一種延遲執行機制,可以最佳化查詢效能並提升記憶體使用效率。此外,我們還會介紹 Polars 表示式,這是一種強大的工具,可以進行各種資料轉換、過濾和彙總操作。最後,我們將比較 Polars 和 Pandas 的差異,並說明如何在實際應用中選擇合適的工具。
資料結構與操作
在資料科學中,我們經常遇到各種資料結構,例如系列(Series)和資料框(DataFrame)。這些結構使我們能夠以高效且有組織的方式儲存和操作資料。
系列(Series)
系列是一種一維的資料結構,類別似於列表,但具有更多的功能。它可以用來儲存同型別的資料,例如整數、浮點數或日期。下面是一個系列的範例:
import polars as pl
myseries = pl.Series([11, 12, 13, 14, 15], name="mynumbers")
print(myseries)
print(myseries.sum())
輸出結果:
shape: (5,)
Series: 'mynumbers' [i64]
[
11
12
13
14
15
]
65
資料框(DataFrame)
資料框是一種二維的資料結構,類別似於表格或矩陣。它可以用來儲存多種型別的資料,例如整數、浮點數、日期和字串。下面是一個資料框的範例:
import polars as pl
from datetime import datetime
mydf = pl.DataFrame(
{
"myint": [11, 12, 13, 14, 15],
"mydate": [
datetime(2023, 11, 11),
datetime(2023, 11, 12),
datetime(2023, 11, 13),
datetime(2023, 11, 14),
datetime(2023, 11, 15),
],
"myfloat": [4.0, 5.0, 6.0, 7.0, 8.0],
"mycity": ['Hyderabad', 'Delhi', 'Durg', 'Bhilai', 'Raipur']
}
)
print(mydf)
資料框提供了許多有用的方法,例如 head()
、tail()
、sample()
和 `describe()”,可以用來檢視和操作資料。
資料框操作
head()
: 回傳資料框的前幾行資料,預設為5行。tail()
: 回傳資料框的後幾行資料,預設為5行。sample()
: 回傳資料框的隨機樣本。describe()
: 回傳資料框的摘要統計資訊。
print(mydf.head(2))
這將回傳資料框的前2行資料。
資料分析:使用 Pandas 進行資料探索
在進行資料分析時,瞭解資料的基本結構和統計特性是非常重要的。Pandas 是 Python 中一個強大的資料分析函式庫,提供了多種方法來探索和分析資料。
使用 tail()
方法
tail()
方法可以用來檢視資料框架(DataFrame)的最後幾行。預設情況下,它會傳回最後 5 行的資料,但你也可以指定要傳回的行數。例如,mydf.tail(2)
會傳回資料框架的最後 2 行。
使用 sample()
方法
sample()
方法可以用來從資料框架中隨機抽取指定數量的行。例如,mydf.sample(2)
會從資料框架中隨機傳回 2 行資料。
使用 describe()
方法
describe()
方法可以用來檢視資料框架的快速摘要統計。它會傳回各個欄位的計數、均值、標準差等統計資訊。這對於快速瞭解資料的分佈和特性非常有用。
實際應用
以下是使用上述方法的實際應用範例:
import pandas as pd
# 建立一個示例資料框架
data = {'myint': [1, 2, 3, 4, 5],
'mydate': ['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04', '2022-01-05'],
'myfloat': [1.1, 2.2, 3.3, 4.4, 5.5],
'mycity': ['臺北', '新竹', '臺中', '高雄', '臺南']}
mydf = pd.DataFrame(data)
# 檢視最後 2 行資料
print(mydf.tail(2))
# 隨機抽取 2 行資料
print(mydf.sample(2))
# 檢視資料框架的摘要統計
print(mydf.describe())
這個範例建立了一個示例資料框架,然後使用 tail()、sample()
和 describe()
方法來探索資料。
內容解密:
上述程式碼中,我們首先匯入了 Pandas 函式庫,然後建立了一個示例資料框架 mydf
。接下來,我們使用 tail(2)
方法來檢視最後 2 行資料,使用 sample(2)
方法來隨機抽取 2 行資料,最後使用 describe()
方法來檢視資料框架的摘要統計。
圖表翻譯:
flowchart TD A[建立資料框架] --> B[使用 tail() 方法] B --> C[使用 sample() 方法] C --> D[使用 describe() 方法] D --> E[檢視摘要統計]
這個流程圖展示了我們如何使用 Pandas 的不同方法來探索資料框架,並最終檢視摘要統計。
使用 Polars 進行資料分析
Polars 是一種強大的資料分析函式庫,提供了高效的資料處理和分析功能。以下是使用 Polars 進行資料分析的範例。
載入 iris.csv 資料集
首先,我們需要載入 iris.csv 資料集。這個資料集包含了 150 個 iris 花的測量資料,包括 sepal length、sepal width、petal length 和 petal width 等屬性。
import polars as pl
# 載入 iris.csv 資料集
df = pl.read_csv("iris.csv")
顯示資料集資訊
接下來,我們可以顯示資料集的資訊,包括資料集的形狀和前幾行的資料。
# 顯示資料集的形狀
print(df.shape)
# 顯示前 5 行的資料
print(df.head())
轉換為 Pandas 資料框
如果需要,我們可以將 Polars 資料框轉換為 Pandas 資料框。
# 轉換為 Pandas 資料框
df_pandas = df.head().to_pandas()
print(df_pandas)
顯示資料集的資料型別
最後,我們可以顯示資料集的資料型別。
# 顯示資料集的資料型別
print(df.dtypes)
內容解密:
pl.read_csv("iris.csv")
:載入 iris.csv 資料集。df.shape
:顯示資料集的形狀。df.head()
:顯示前幾行的資料。df.head().to_pandas()
:轉換為 Pandas 資料框。df.dtypes
:顯示資料集的資料型別。
圖表翻譯:
flowchart TD A[載入 iris.csv 資料集] --> B[顯示資料集資訊] B --> C[轉換為 Pandas 資料框] C --> D[顯示資料集的資料型別]
圖表說明:
- 圖表顯示了使用 Polars 進行資料分析的流程。
- 首先,載入 iris.csv 資料集。
- 接下來,顯示資料集的資訊,包括資料集的形狀和前幾行的資料。
- 然後,轉換為 Pandas 資料框。
- 最後,顯示資料集的資料型別。
資料選擇與過濾
在資料分析中,選擇和過濾資料是非常重要的步驟。以下將介紹如何使用Python進行資料選擇和過濾。
資料型別檢視
首先,我們可以使用 dtypes
屬性來檢視資料框架中每個欄位的資料型別。
print(mydf.dtypes)
這將顯示每個欄位的資料型別,例如整數、浮點數或字串等。
資料選擇
接下來,我們可以使用索引來選擇資料框架中的特定資料。例如,我們可以使用 mydf[0, :]
來選擇第一行的所有欄位。
print(mydf[0, :])
這將顯示第一行的所有欄位資料。
資料過濾
我們也可以使用條件式來過濾資料。例如,我們可以使用 mydf[:, ['sepal.length', 'petal.length']].head(2)
來選擇前兩行的 sepal.length
和 petal.length
欄位。
print(mydf[:, ['sepal.length', 'petal.length']].head(2))
這將顯示前兩行的 sepal.length
和 petal.length
欄位資料。
隨機抽樣
另外,我們可以使用 sample()
方法來隨機抽樣資料框架中的資料。例如,我們可以使用 mydf.sample(5).to_pandas
來隨機抽樣 5 行資料。
print(mydf.sample(5).to_pandas)
這將顯示隨機抽樣的 5 行資料。
圖表翻譯:
flowchart TD A[資料框架] --> B[檢視資料型別] B --> C[選擇資料] C --> D[過濾資料] D --> E[隨機抽樣]
內容解密:
以上程式碼展示瞭如何使用Python進行資料選擇和過濾。首先,我們使用 dtypes
屬性來檢視資料框架中每個欄位的資料型別。接下來,我們使用索引來選擇資料框架中的特定資料。然後,我們使用條件式來過濾資料。最後,我們使用 sample()
方法來隨機抽樣資料框架中的資料。
資料操作與分析
在資料分析中,能夠有效地選擇和操作資料是非常重要的。以下將示範如何使用 Python 和 Pandas 進行資料選擇、新增欄位、篩選資料以及計算唯一值的數量。
選擇特定欄位
首先,我們可以使用 select
方法選擇特定的欄位。例如,若要選擇 sepal.width
、petal.width
和 variety
欄位,並顯示前 4 行資料,可以使用以下程式碼:
print(mydf.select(['sepal.width', 'petal.width', 'variety']).head(4))
這將傳回一個新的 DataFrame,只包含選擇的欄位和前 4 行資料。
新增欄位
新增欄位可以使用 with_columns
方法。例如,若要新增一個名為 Mux10_Petal.Length
的欄位,其值為 petal.length
乘以 10,並顯示前 3 行資料,可以使用以下程式碼:
print(mydf.with_columns([
('Mux10_Petal.Length', mydf['petal.length'] * 10)
]).head(3))
這將傳回一個新的 DataFrame,包含新增的欄位和前 3 行資料。
篩選資料
篩選資料可以使用 filter
方法。例如,若要篩選 variety
欄位為 Setosa
的資料,並顯示最後 5 行資料,可以使用以下程式碼:
print(mydf.filter(mydf['variety'] == 'Setosa').tail(5))
這將傳回一個新的 DataFrame,只包含篩選的資料和最後 5 行。
計算唯一值的數量
計算唯一值的數量可以使用 nunique
方法。例如,若要計算 sepal.width
欄位的唯一值數量,可以使用以下程式碼:
print(mydf['sepal.width'].nunique())
這將傳回 sepal.width
欄位的唯一值數量。
內容解密:
以上程式碼示範瞭如何使用 Pandas 進行資料選擇、新增欄位、篩選資料以及計算唯一值的數量。每個步驟都使用了不同的方法和引數,以達到不同的目的。瞭解這些方法和引數的使用方式,可以幫助您更有效地進行資料分析和操作。
圖表翻譯:
flowchart TD A[資料選擇] --> B[篩選資料] B --> C[新增欄位] C --> D[計算唯一值] D --> E[傳回結果]
此圖表展示了資料操作的流程,從資料選擇開始,接著是篩選資料、新增欄位,然後是計算唯一值,最終傳回結果。每個步驟都與前面的步驟相連,形成了一個完整的流程。
資料分析與視覺化
在進行資料分析時,瞭解資料的統計特性是非常重要的。以下是如何使用 Python 進行資料分析和視覺化的範例。
資料統計分析
首先,我們需要計算整個 sepal.length
欄位的統計資料。這包括最小值、平均值、中位數、最大值和標準差等。
import polars as pl
import pandas as pd
import matplotlib.pyplot as plt
# 載入資料
mydf = pl.read_csv("your_data.csv")
# 計算統計資料
stats = mydf.select([
pl.min("sepal.length").alias("min_sepal_length"),
pl.mean("sepal.length").alias("mean_sepal_length"),
pl.median("sepal.length").alias("median_sepal_length"),
pl.max("sepal.length").alias("max_sepal_length"),
pl.std("sepal.length").alias("std_sepal_length")
])
print(stats)
系列級別統計分析
接下來,我們可以在系列級別上計算統計資料。這對於理解每個欄位的分佈非常有用。
# 系列級別統計分析
series_stats = mydf.select([
pl.col("sepal.length").min().alias("min_sepal_length"),
pl.col("sepal.length").mean().alias("mean_sepal_length"),
pl.col("sepal.length").median().alias("median_sepal_length"),
pl.col("sepal.length").max().alias("max_sepal_length"),
pl.col("sepal.length").std().alias("std_sepal_length")
])
print(series_stats)
Polars 資料處理與 Pandas 資料視覺化
最後,我們可以使用 Polars 進行資料處理,然後使用 Pandas 進行資料視覺化。
# 使用 Polars 進行資料處理
mysepal_length = mydf.select([
"sepal.length"
])
# 將資料轉換為 Pandas DataFrame
mysepal_length_df = mysepal_length.to_pandas()
# 使用 Pandas 進行資料視覺化
mysepal_length_df.hist(bins=10)
plt.show()
這些範例展示瞭如何使用 Python 進行資料分析和視覺化,包括計算統計資料、系列級別統計分析和使用不同函式庫進行資料處理和視覺化。
資料視覺化與群組運算
資料視覺化是將資料轉換為圖形或圖表的過程,讓人們更容易理解和分析資料。在 Python 中,有許多函式庫可以用於資料視覺化,例如 Matplotlib 和 Polars。
使用 Polars 進行資料視覺化
Polar 是一個快速且高效的資料處理函式庫,提供了許多功能用於資料視覺化。以下是使用 Polars 進行資料視覺化的範例:
import polars as pl
# 讀取 iris.csv 資料集
mydf = pl.read_csv("iris.csv")
# 對 variety 列進行群組運算
grouped_df = mydf.groupby("variety")
# 對每個群組計算非空值的數量
agg_df = grouped_df.agg(pl.count())
# 顯示結果
print(agg_df)
群組運算的過程
群組運算是指將資料分成多個群組,然後對每個群組進行運算。以下是群組運算的過程:
- 群組: 對資料進行群組,根據指定的欄位(例如 variety)。
- 運算: 對每個群組進行運算,例如計算非空值的數量。
- 結果: 將每個群組的運算結果合併成一個新的資料框。
使用 Polars 進行群組運算
Polar 提供了 groupby
函式用於群組運算,以下是使用 Polars 進行群組運算的範例:
import polars as pl
# 讀取 iris.csv 資料集
mydf = pl.read_csv("iris.csv")
# 對 variety 列進行群組運算
grouped_df = mydf.groupby("variety")
# 對每個群組計算非空值的數量
agg_df = grouped_df.agg(pl.count())
# 顯示結果
print(agg_df)
圖表翻譯:
graph LR A[讀取資料] --> B[群組運算] B --> C[計算非空值數量] C --> D[顯示結果]
內容解密:
以上程式碼使用 Polars 進行資料視覺化和群組運算。首先,讀取 iris.csv 資料集,然後對 variety 列進行群組運算。接著,對每個群組計算非空值的數量,最後顯示結果。這個過程可以幫助我們更好地理解資料的結構和分佈。
使用 Polars 進行資料操作
Polars 是一種強大的資料操作函式庫,提供了多種方式來操縱和計算資料。其中,Polars 表示式是一個重要的功能,讓使用者可以以多種方式來轉換、過濾和彙總資料。
資料轉換
Polars 表示式可以用於進行資料轉換,例如進行算術運算、字串操作、日期和時間操作等。這些表示式可以用來建立新的欄位或編輯現有的欄位,以符合使用者的需求。
資料過濾和選擇
使用 Polars 表示式,可以過濾和選擇特定的資料列或欄位,根據預先定義的條件。這些表示式可以用來建立複雜的資料選擇規則和過濾條件。
資料彙總
Polars 表示式也可以用於彙總資料,例如計算平均值、計數、最大值、最小值等。這些表示式可以用來產生彙總統計和資料摘要。
資料結合和合併
使用 Polars 表示式,可以結合多個資料集,根據分享的欄位或合併多個資料源。
效能最佳化
Polars 使用懶評估(lazy evaluation)來最佳化和加速計算。Polars 可以最佳化執行計畫和以懶散和平行化的方式執行操作,從而實作更快和更有效的資料處理。
範例程式
以下是使用 Polars 進行資料操作的範例程式:
import polars as pl
# 讀取 iris.csv 資料集
mydf = pl.read_csv("iris.csv")
# 使用 select 方法進行多個表示式操作
selected_data = mydf.select([
pl.col("sepal.length").filter(pl.col("sepal.length") > 5.0),
pl.col("petal.length").sort("petal.length")
])
# 顯示選擇和過濾的資料
print(selected_data)
這個範例程式展示瞭如何使用 Polars 進行資料操作,包括資料轉換、過濾和選擇、彙總和結合等。
Polars 的 Lazy API 概念
Polars 的 Lazy API 是指其延遲評估機制,允許使用者建立計算計畫而不立即執行。相反,操作只在結果被明確請求或當動作被執行時才被執行。Lazy API 的優點包括:
- 最佳化:延遲評估允許 Polars 最佳化執行計畫,從而提高計算效率和效能。
- 記憶體效率:延遲評估意味著中間結果不會被實際化,除非明確請求,這減少了記憶體使用,特別是在處理大資料集或複雜計算時。
- 靈活性:Lazy API 的靈活性使得建立複雜的計算管道變得可能。使用者可以定義一系列操作和轉換,而不需要立即執行它們。
Polars 與 Pandas 的差異
Polars 的 Lazy API 與 Pandas 在計算模型和資料處理方法上有所不同:
- 評估模型:Pandas 中的操作通常是即時執行的,而 Polars 使用延遲評估,操作被構建成計算計畫,而不是立即執行。
- 最佳化:Polars 利用延遲評估來最佳化執行計畫,根據可用的最佳化(如 predicate pushdown 和 projection pushdown)重新排列和最佳化過程。
Lazy Evaluation 的優點
Lazy Evaluation 可以防止中間結果被實際化,除非明確請求,這減少了記憶體使用。另外,Polars 的 Lazy Evaluation 方式還可以促進操作的平行執行,利用現代多核心 CPU 自動跨多個執行緒或核心進行計算。
示例程式
以下是一個示例程式(Chap10_Example10.7.py),展示了 Lazy Evaluation 的使用:
import polars as mypl
# 讀取 iris.csv 資料集並儲存在 mydf 變數中
mydf = mypl.read_csv("iris.csv")
# 定義一個 Lazy 計算計畫
mylazy_plan = mydf.lazy().select([mypl.col("sepal.length") > 5.0]).sort("petal.length")
# 執行計算計畫並取得結果
myresult = mylazy_plan.collect()
# 顯示結果
print(myresult)
在這個示例中,我們讀取 iris.csv 資料集到一個名為 mydf 的 DataFrame 中。然後,我們定義一個 Lazy 計算計畫,使用 lazy()
方法在 DataFrame 上連結多個操作(如選擇、過濾和排序)。但是,這個計畫不會立即被執行。要執行計畫並取得結果,我們在 Lazy 計畫上呼叫 collect()
方法。最終,我們顯示結果。
Streaming 的使用
Lazy Evaluation 還可以與 Streaming 結合使用,允許使用者在資料可用時即時處理或分析資料。以下是如何修改上述程式碼以啟用 Streaming 的示例:
myresult = mylazy_plan.stream()
這樣,收集的結果將以 Streaming 方式傳回,允許實時處理資料。
探索 Polars 中的表示式
在前一章中,我們探討了 Pandas 和 Polars 之間的差異,強調了 Polars 在處理大型資料集方面的優異效能。我們深入瞭解了 Polars 的獨特資料型別,包括數值、巢狀、時間和其他群組,以及其基礎資料結構,如系列和資料框架。同時,我們還闡述了 Polars 中的上下文,關注基本操作、選擇和過濾概念,以及群組操作。我們強調了表示式在 Polars 中的重要性,並介紹了 Lazy API 的概念,它透過最佳化計算來提高效能。
在本章中,瞭解 Polars 中的表示式概念至關重要,因為我們將探索基本運運算元、列選擇、函式、轉換、字串操作、聚合技術、處理缺失資料、折疊以及使用列表和陣列等主題。同時,我們還將研究 NumPy 在 Polars 中的整合,為這兩個強大的函式庫之間提供了一個橋樑。此外,我們將進行 Pandas 和 Polars 之間的操作比較,以凸顯每個框架在不同場景下的優勢和限制,幫助使用者在進行資料處理任務時做出明智的決定。
表示式概念
Polars 中的表示式是一種強大的工具,允許使用者執行複雜的資料轉換和操作。它們可以用於選擇特定的列、過濾行、執行聚合操作等。表示式可以是基本運運算元,如加法和減法,也可以是更複雜的函式,如字串操作和資料轉換。
基本運運算元
Polars 支援各種基本運運算元,包括算術運運算元、比較運運算元和邏輯運運算元。這些運運算元可以用於執行簡單的資料轉換和操作。
列選擇
Polars 允許使用者選擇特定的列進行操作。這可以透過使用 select
方法來實作。
函式
Polars 提供了各種內建函式,包括數學函式、字串函式和日期函式等。這些函式可以用於執行複雜的資料轉換和操作。
轉換
Polars 支援各種資料型別轉換,包括整數、浮點數、字串和日期等。這些轉換可以透過使用 cast
方法來實作。
字串操作
Polars 提供了各種字串操作函式,包括字串拼接、字串分割和字串替換等。
聚合技術
Polars 支援各種聚合技術,包括求和、平均值、最大值和最小值等。這些聚合可以透過使用 agg
方法來實作。
處理缺失資料
Polars 提供了各種方法來處理缺失資料,包括填充缺失值和刪除含有缺失值的行等。
折疊
Polars 支援折疊操作,可以用於執行複雜的資料轉換和操作。
使用列表和陣列
Polars 允許使用者使用列表和陣列進行資料操作。這可以透過使用 list
和 array
方法來實作。
NumPy 整合
Polars 支援 NumPy 的整合,可以用於執行高效能的資料操作。這個整合可以透過使用 numpy
方法來實作。
操作比較
Pandas 和 Polars 是兩個流行的 Python 資料處理函式庫。雖然它們都提供了強大的資料處理功能,但它們在效能、易用性和功能上有所不同。在本章中,我們將進行 Pandas 和 Polars 之間的操作比較,以凸顯每個框架在不同場景下的優勢和限制。
效能比較
Polars 的效能優於 Pandas,特別是在處理大型資料集方面。Polars 的 columnar 資料結構和 Rust 實作使其能夠更快地執行資料操作。
易用性比較
Pandas 的易用性優於 Polars,特別是在進行簡單的資料操作方面。Pandas 的 API 更加簡單和直觀,使其更容易上手。
功能比較
Polars 的功能優於 Pandas,特別是在進行複雜的資料轉換和操作方面。Polars 提供了更多的內建函式和方法,使其能夠執行更複雜的資料操作。
從技術架構視角來看,Polars 和 Pandas 作為 Python 資料處理的工具,各有千秋。深入剖析兩者核心設計理念,Polars 的 columnar 資料結構和 Rust 實作賦予其在大型資料集處理上的顯著效能優勢,尤其在多核心 CPU 的平行運算中更為突出。相對而言,Pandas 更偏向易用性,其 row-based 結構和 Python 實作讓使用者能快速上手,語法簡潔直觀。然而,在大資料場景下,Pandas 的效能瓶頸則較為明顯。技術選型的關鍵在於權衡專案需求,若著重處理速度和資源效率,Polars 應是首選;若追求開發便捷性和快速原型設計,則 Pandas 更為適合。對於重視長期效能的專案,玄貓認為,Polars 代表了未來資料處理的趨勢,值得及早佈局並深入研究其表示式系統和 Lazy API 的應用,以充分發揮其效能潛力。