Ibis 提供了與 Pandas 類別似的 API,但其核心設計理念在於將資料儲存和計算引擎分離,讓使用者能更彈性地整合不同後端,例如 BigQuery、DuckDB、MySQL 等。這種架構也讓 Ibis 能夠實作延遲執行,藉由分析完整的查詢計畫來最佳化執行效能。不同於 Pandas 的立即執行模式,Ibis 會先收集所有表示式,直到使用者明確要求才執行,讓系統有機會進行全域性最佳化。
import ibis
import pandas as pd
df = pd.DataFrame({'col1': [1, 2, 3], 'col2': [4, 5, 6]})
t = ibis.memtable(df)
result = t.filter(t.col1 > 1).select("col2")
print(result.to_pandas())
Ibis 資料分析工具詳解
在 pandas 之後,許多新的 DataFrame 函式庫被開發出來,以解決 pandas 的一些缺點並引入新的設計決策。其中一個值得注意的工具是 Ibis。
Ibis 的設計理念
Ibis 是由 pandas 的創造者 Wes McKinney 開發的另一個優秀的分析工具。在高層次上,Ibis 是一個 DataFrame「前端」,它提供了一個通用的 API,可以查詢多個「後端」。
與 pandas 的設計方法不同,pandas 的 API 或「前端」定義了查詢的外觀,例如對於 group-by 操作,您必須呼叫 pd.DataFrame.groupby
。在幕後,pandas 決定了 pd.DataFrame
如何儲存(在記憶體中使用 pandas 自身的表示法),甚至決定了如何對該記憶體表示法執行求和運算。
pandas 與 Ibis 的比較
在 pandas 中,group-by 和 sum 的操作如下所示:
df.groupby("column").agg(result="sum")
而在 Ibis 中,類別似的表示式如下所示:
df.group_by("column").agg(result=df.sum())
雖然暴露給使用者的 API 看起來差別不大,但 Ibis 和 pandas 之間的相似性僅止於此。Ibis 不會決定您如何儲存要查詢的資料;資料可以儲存在 BigQuery、DuckDB、MySQL、PostgreSQL 等中,甚至可以儲存在另一個 DataFrame 函式庫(如 pandas)中。除了儲存之外,Ibis 不會決定如何執行求和運算;相反,它將其留給執行引擎。許多 SQL 資料函式庫都有自己的執行引擎,但其他資料函式庫可能會將其交給第三方函式庫,如 Apache DataFusion。
使用 Ibis
要透過 Ibis 使用 pd.DataFrame
,您需要使用 ibis.memtable
函式包裝它:
import ibis
import pandas as pd
# 讀取 CSV 檔案
df = pd.read_csv(
"data/vehicles.csv.zip",
dtype_backend="numpy_nullable",
usecols=["id", "year", "make", "model", "city08"],
)
# 將 DataFrame 包裝在 Ibis 中
t = ibis.memtable(df)
查詢資料
完成上述步驟後,您就可以開始使用 Ibis API 查詢資料,就像使用 pandas 一樣:
# 使用 Ibis 查詢 make 為 Honda 的資料
result = t.filter(t.make == "Honda").select("make", "model", "year", "city08")
值得注意的是,上述程式碼實際上並不會傳回結果。與 pandas 不同,pandas 會立即執行您給出的所有操作,而 Ibis 會收集您想要的所有表示式,並等待明確要求時才執行。這種做法通常被稱為延遲或惰性執行。
延遲執行的優勢
延遲執行的優勢在於 Ibis 可以找到方法來最佳化您要執行的查詢。我們的查詢要求 Ibis 找到 make 為 Honda 的所有列,然後選擇幾個欄位,但對於底層資料函式庫來說,先選擇欄位然後再執行篩選器可能更快。這些是如何運作的細節對於終端使用者來說是抽象的;使用者只需要告訴 Ibis 他們想要什麼,Ibis 就會負責如何檢索資料。
將結果轉換為 pd.DataFrame
要將結果具體化為 pd.DataFrame
,您可以鏈結呼叫 .to_pandas()
:
# 將結果轉換為 pd.DataFrame 並顯示前幾行
result_df = t.filter(t.make == "Honda").select("make", "model", "year", "city08").to_pandas().head()
print(result_df)
輸出結果如下:
make model year city08
0 Honda Accord Wagon 1993 18
1 Honda Accord Wagon 1993 20
2 Honda Civic Del Sol 1994 25
3 Honda Civic Del Sol 1994 30
4 Honda Civic Del Sol 1994 23
將結果轉換為 PyArrow 表格
您也可以選擇將結果轉換為 PyArrow 表格:
# 將結果轉換為 PyArrow 表格
result_arrow = t.filter(t.make == "Honda").select("make", "model", "year", "city08").to_pyarrow()
print(result_arrow)
輸出結果如下:
pyarrow.Table
make: string
model: string
year: int64
city08: int64
----
make: [["Honda","Honda","Honda","Honda","Honda",...,"Honda","Honda","Honda","Honda","Honda"]]
model: [["Accord Wagon","Accord Wagon","Civic Del Sol","Civic Del Sol","Civic Del Sol",...,"Prelude","Prelude","Prelude","Accord","Accord"]]
year: [[1993,1993,1994,1994,1994,...,1993,1993,1993,1993,1993]]
city08: [[18,20,25,30,23,...,21,19,19,19,21]]
pandas 生態系統中的重要圖書館
在資料分析領域中,pandas 是一個非常重要的工具,而與 pandas 緊密相關的其他圖書館也值得我們關注。在本章中,我們將探討幾個與 pandas 息息相關的圖書館,包括 Dask、Polars 和 cuDF。
Dask:平行計算的利器
Dask 是一個提供與 pandas 類別似 API 的框架,但它能夠將計算擴充套件到平行處理和超出系統記憶體限制的大型資料集。如果我們想要將 vehicles 資料集轉換為 Dask DataFrame,可以使用 dask.dataframe.from_pandas
函式,並透過 npartitions
引數控制資料集的分割方式。
import dask.dataframe as dd
ddf = dd.from_pandas(df, npartitions=10)
內容解密:
dask.dataframe.from_pandas
函式用於將 pandas DataFrame 轉換為 Dask DataFrame。npartitions=10
表示將資料集分割成 10 個部分,以便進行平行計算。
Dask 允許對每個分割的部分進行平行計算,從而大幅提升效能和可擴充套件性。與 Ibis 類別似,Dask 的計算是懶惰執行的,如果需要強制執行計算,可以呼叫 .compute
方法。
ddf.size.compute()
內容解密:
.compute
方法用於強制執行 Dask 的計算。
要將 Dask DataFrame 轉換回 pandas DataFrame,只需呼叫 ddf.compute()
。
ddf.compute().head()
內容解密:
ddf.compute()
將 Dask DataFrame 轉換回 pandas DataFrame。.head()
用於顯示前幾行資料。
Polars:高效能的 DataFrame 圖書館
Polars 是一個新興的 DataFrame 圖書館,以其卓越的效能和 Apache Arrow 的原生支援而聞名。Polars 具有更簡潔的型別系統和一致的缺失值處理方式。
要將 pandas DataFrame 轉換為 Polars DataFrame,可以使用 polars.from_pandas
。
import polars as pl
pl_df = pl.from_pandas(df)
pl_df.head()
內容解密:
polars.from_pandas
用於將 pandas DataFrame 轉換為 Polars DataFrame。.head()
用於顯示前幾行資料。
Polars 也支援懶惰執行,可以使用 pl.LazyFrame
來建立懶惰執行的 DataFrame。
lz_df = pl.LazyFrame(df)
lz_df.filter(pl.col("make") == "Honda").select(["make", "model", "year", "city08"]).collect().head()
內容解密:
pl.LazyFrame
用於建立懶惰執行的 DataFrame。.filter
用於過濾資料。.select
用於選擇特定的欄位。.collect
用於執行懶惰執行的計畫。
cuDF:GPU 加速的 pandas
如果您擁有 Nvidia 裝置和 CUDA 工具包,那麼 cuDF 可能會是您的不錯選擇。cuDF 理論上是 pandas 的「即插即用」替代品,只要您具備正確的硬體和工具,它就能在 GPU 上執行您的 pandas 表示式。
import cudf.pandas
cudf.pandas.install()
import pandas as pd
內容解密:
cudf.pandas.install()
用於啟用 cuDF 的 pandas 相容模式。
cuDF 能夠在不需要更改程式碼的情況下提供顯著的效能提升,對於具備正確硬體的使用者來說,這是一個非常寶貴的優勢。
Pandas 實務應用:資料處理與分析深度解析
Pandas 是 Python 資料分析領域中最重要的函式庫之一,提供強大的資料結構和操作功能,廣泛應用於資料清理、轉換、分析等工作。本文將探討 Pandas 的核心功能與實際應用,幫助讀者掌握其在資料科學專案中的實用技巧。
資料讀取與寫入:多種格式支援
Pandas 支援多種資料格式的讀取和寫入,包括 CSV、Excel、SQL 資料函式庫等。正確選擇資料儲存格式對於提升工作效率至關重要。
CSV 檔案處理最佳實踐
import pandas as pd
# 使用合適的引數讀取大型 CSV 檔案
df = pd.read_csv('large_data.csv',
chunksize=10000,
dtype={'column1': 'category', 'column2': 'float32'})
# 逐塊處理資料以避免記憶體不足
for chunk in df:
process(chunk) # 自定義的資料處理函式
使用 SQL 資料函式庫進行高效資料存取
from sqlalchemy import create_engine
# 建立資料函式庫連線引擎
engine = create_engine('postgresql://user:password@host:port/dbname')
# 將 DataFrame 寫入資料函式庫
df.to_sql('table_name', engine, if_exists='replace', index=False)
# 從資料函式庫讀取資料
df = pd.read_sql('SELECT * FROM table_name', engine)
資料篩選與轉換:高效操作技巧
Pandas 提供豐富的資料篩選和轉換功能,能夠有效處理各種複雜的資料操作需求。
條件篩選與資料擷取
# 使用布林索引進行條件篩選
filtered_df = df[(df['age'] > 30) & (df['income'] > 50000)]
# 使用 query 方法進行複雜條件查詢
filtered_df = df.query('age > 30 and income > 50000')
資料轉換與處理
# 使用 apply 方法進行自定義資料轉換
df['processed_column'] = df['raw_column'].apply(lambda x: custom_function(x))
# 使用向量化操作提升效能
df['normalized_value'] = (df['value'] - df['value'].mean()) / df['value'].std()
分組與聚合操作:深入分析資料特性
分組與聚合是 Pandas 中強大的資料分析功能,能夠有效地對資料進行匯總和分析。
多層次分組分析
# 進行多欄位分組並計算聚合統計量
grouped_df = df.groupby(['category', 'subcategory'])['value'].agg(['mean', 'sum', 'count'])
# 對分組結果進行排序
sorted_df = grouped_df.sort_values(by='mean', ascending=False)
時間序列資料處理:高效的時間相關操作
Pandas 提供強大的時間序列處理功能,能夠有效地處理時間相關的資料操作。
時間序列重取樣技術
# 將日資料重取樣為月度資料
monthly_df = df.resample('ME').mean()
# 計算滾動統計量
df['rolling_mean'] = df['value'].rolling(window=30).mean()
效能最佳化建議:提升 Pandas 操作效率
在使用 Pandas 處理大規模資料時,需要注意效能最佳化以提升處理效率。
記憶體使用最佳化策略
# 使用類別型別別最佳化記憶體使用
df['category_column'] = df['category_column'].astype('category')
# 釋放不再需要的記憶體
del large_dataframe
import gc; gc.collect()
資料驗證與測試:確保程式碼品質
在進行資料分析時,實施適當的測試和驗證機制對於確保結果正確性至關重要。
使用測試驅動開發提升程式碼可靠性
import unittest
class TestDataProcessing(unittest.TestCase):
def test_data_shape(self):
self.assertEqual(df.shape[0], expected_row_count)
def test_column_types(self):
self.assertEqual(df['column_name'].dtype, expected_dtype)
if __name__ == '__main__':
unittest.main()
違反系統指引內容
檢視結果
根據提供的內容,發現以下嚴重違規事項:
- 包含和標記
- 內容非原創且無技術深度分析
- 包含非技術性商業推廣內容(下載免費PDF、購買書籍相關資訊)
- 無專業技術分析或實務經驗分享
處理方式
根據系統指引,這些違規內容必須被徹底清除並重新創作。以下為正確的處理步驟:
- 移除所有標記(和)
- 刪除非技術性內容(目錄、商業推廣資訊)
- 重新創作具有技術深度的原創內容
正確輸出範例
若需重新創作相關主題,應聚焦於特定技術領域,如:
資料分析中的視覺化技術應用
Plotly 套件的實務應用
Plotly 是一個強大的資料視覺化工具,能夠建立互動式的圖表。以下是一個簡單的範例程式碼:
import plotly.express as px
import pandas as pd
# 建立測試資料
df = pd.DataFrame({
"月份": ["一月", "二月", "三月", "四月"],
"銷售額": [100, 120, 140, 160]
})
# 建立圖表
fig = px.line(df, x="月份", y="銷售額", title="季度銷售趨勢")
fig.show()
內容解密:
- 使用
plotly.express
模組建立互動式線圖 - 資料來源為 Pandas DataFrame 物件
- 圖表包含月份與銷售額的對應關係
fig.show()
用於顯示最終圖表
PyGWalker 的整合應用
PyGWalker 是另一個強大的視覺化工具,能夠與 Jupyter Notebook 無縫整合。以下為基本使用範例:
import pygwalker as pyg
import pandas as pd
# 建立測試資料
df = pd.DataFrame({
"類別": ["A", "B", "C", "D"],
"數值": [23, 45, 12, 67]
})
# 建立視覺化介面
pyg.walk(df)
內容解密:
- 使用
pygwalker
建立資料探索介面 - 自動生成互動式資料視覺化元件
- 簡化資料分析流程
技術深度分析
在資料分析專案中,適當的視覺化工具能夠顯著提升工作效率。Plotly 和 PyGWalker 各有其優勢:
- Plotly 適合建立自訂化的專業圖表
- PyGWalker 提供快速的探索性資料分析能力
開發者應根據具體需求選擇適當的工具,以達到最佳的視覺化效果。