平常在資料清理的時候,都會想到如果是利用 Python 我們會怎麼操作資料清理跟截取呢。於是產生了這一篇文章的想法,讓我們來使用 pandas + duckdb 來實現吧!
1.使用工具
-
Python — 建立資料
- pandas
- pd.DataFrame
- print()
-
duckdb — SQL 翻譯官
- duckdb.execute()
- duckdb.query().to_df()
- SQL: CREATE OR REPLACE VIEW
- select
- coalesce()
- round
- left join
- group by
- order by
- where
- 程式碼
import duckdb
import pandas as pd
# ----------------------------------------------------
# 步驟 1:用 Pandas 模擬讀取原始資料
# ----------------------------------------------------
# 員工表(包含一位還沒分配部門的新人「小李」)
df_employees = pd.DataFrame(
{
"emp_id": [101, 102, 103, 104, 105],
"name": ["阿明", "小華", "大強", "美美", "小李"],
"dept_id": ["D01", "D02", "D01", "D03", None], # 小李暫無部門
"salary": [60000, 75000, 55000, 90000, 50000],
}
)
# 部門表
df_departments = pd.DataFrame(
{
"dept_id": ["D01", "D02", "D03"],
"dept_name": ["研發部", "市場部", "財務部"]
}
)
# ----------------------------------------------------
# 步驟 2:用 VIEW 把複雜語法打包成「虛擬資料集」
# ----------------------------------------------------
# 1. 使用 OR REPLACE 確保重複執行程式時,會自動覆蓋舊邏輯而不報錯
# 2. 使用 LEFT JOIN 確保左表(員工)一個都不漏
# 3. 使用 COALESCE 把沒對到部門的 NULL 欄位漂亮地補上 '未分配'
duckdb.execute(
"""
CREATE OR REPLACE VIEW v_dept_summary AS
SELECT
COALESCE(d.dept_name, '未分配部門') AS 部門,
COUNT(e.emp_id) AS 總人數,
ROUND(AVG(e.salary), 0) AS 平均薪資
FROM df_employees AS e
LEFT JOIN df_departments AS d ON e.dept_id = d.dept_id
GROUP BY d.dept_name, e.dept_id
"""
)
# ----------------------------------------------------
# 步驟 3:在 Python 裡直接呼叫與二次利用這個資料集
# ----------------------------------------------------
# 應用 A:撈出整張整理好的報表,並加上排序
df_all = duckdb.query("SELECT * FROM v_dept_summary ORDER BY 平均薪資 DESC").to_df()
# 應用 B:針對同一個資料集做二次篩選(只要平均薪資大於 60000 的部門)
df_filter = duckdb.query("SELECT * FROM v_dept_summary WHERE 平均薪資 > 60000").to_df()
print("--- 應用 A:呼叫整個資料集並排序(小李被歸在未分配部門) ---")
print(df_all)
print("\n--- 應用 B:呼叫資料集並做二次篩選 ---")
print(df_filter)- 結果
利用 pandas 與 duckdb 是不是能夠快速的讓我們抓取想要的資料呢!
# ----------------------------------------------------
# 結果
# ----------------------------------------------------
--- 應用 A:呼叫整個資料集並排序(小李被歸在未分配部門) ---
部門 總人數 平均薪資
0 財務部 1 90000.0
1 市場部 1 75000.0
2 研發部 2 57500.0
3 未分配部門 1 50000.0
--- 應用 B:呼叫資料集並做二次篩選 ---
部門 總人數 平均薪資
0 市場部 1 75000.0
1 財務部 1 90000.0參考資料:
- Python
- Gemini