用SQL操作Pandas DataFrame的三種方式

新語數據故事匯 發佈 2023-06-03T00:40:18.963165+00:00

假如你現在需要對Pandas的DataFrame進行如下操作:而如果用SQL來書寫,達到上面的處理效果,我們可以寫出更優雅和更易於理解的代碼:雖然我們非常喜歡Python,但很明顯,對數據進行簡單分析時,SQL才是我們最好的朋友,相比於Pandas的聚合函數語法,SQL語法更通俗、直觀、便於理解。

假如你現在需要對PandasDataFrame進行如下操作:

df[df['Origin'] == 'USA']
.groupby('Origin')
.agg({
    'Miles_per_Gallon': ['sum', 'mean'],
    'Acceleration': ['min', 'max'],
}).reset_index()
df.columns=["Origin",
    "Miles_per_Gallon_sum",
    "Miles_per_Gallon_mean",
    "Acceleration_min",
    "Acceleration_max"]

而如果用SQL來書寫,達到上面的處理效果,我們可以寫出更優雅和更易於理解的代碼:

SELECT
    Origin,
    SUM(Miles_per_Gallon) AS sum_Miles,
    AVG(Miles_per_Gallon) AS avg_Miles,
    MIN(Acceleration) AS min_Acceleration,
    MAX(Acceleration) AS max_Acceleration
FROM df
WHERE Origin = 『USA』
GROUP BY 1

雖然我們非常喜歡Python,但很明顯,對數據進行簡單分析時,SQL才是我們最好的朋友,相比於Pandas的聚合函數語法,SQL語法更通俗、直觀、便於理解。

接下來,本文將介紹三種使用SQL來操作Pandas DataFrame數據的方法。

假設我們已經有了一個準備好的DataFrame,其中包含你準備好的數據,下面我們開始介紹用SQL語句來查詢DataFrame數據的方法。

方法1:使用DuckDB來查詢DataFrame

DuckDB是一個開源的內存中的分析型資料庫,專為高效處理分析工作負載而設計。它被稱為SQLite的分析/OLAP等效工具,因為它提供了類似SQL的查詢語言,並支持在Pandas DataFrame上執行SQL查詢。

DuckDB是一個強大而靈活的分析型資料庫,它的集成性和性能優勢使得在Pandas中使用SQL查詢變得更加便捷和高效,首先按照通常的方法進行安裝:

pip install duckdb
import duckdb

DuckDB中的基準查詢:

注意:我們需要明確地將結果轉換為DataFrameDuckDB會自動掃描你的內核,尋找屬於DataFrame的變量,並讓你像查詢表一樣查詢它們。不過這種掃描是在查詢運行時發生的,所以你不能使用如DESCRIBE這樣的語句:

DuckDB對空白更難處理,反斜線不能解析,所以你需要引用表(DataFrame)的名字,然後是列名(帶引號):

DuckDB是專門為OLAP使用案例而設計的資料庫引擎,相較於SQLite,它提供了一些在SQLite中不存在的強大功能。一個例子是DuckDBSAMPLE關鍵字,它使得對數據進行採樣變得非常簡單,特別適用於處理大型數據集的聚合函數。這一功能在數據分析和探索性數據分析(EDA)中非常有用。

或許,你使用DuckDB而不是SQLite來查詢Pandas數據的主要原因是速度。DuckDB聲稱在分析性查詢方面比SQLite快得多,Pandas內置的to_sql和from_sql函數在SQLite中工作得很慢,但在DuckDB中卻相當快,在大數據的聚合基準查詢中,速度的差異是相當大的。

方法2:使用Pandas .query()方法

你可能已經熟悉了Pandas中的.query()函數。它不完全是SQL,但它可以使一些基本的查詢變得更容易,你可以理解它為一個簡單的WHERE或.filter()的等價方法。

query()方法的文檔比較少,你還可以使用&或者and、or、not等邏輯運算符,以及其它常見的操作符(例如==,<,>,!=等)來連接過濾器:

儘管query()方法提供了方便的語法來篩選DataFrame,但它的表達能力相對有限,某些複雜的查詢可能無法使用單個query()表達式解決,需要使用其他方法或技巧來實現。

方法3:使用SmartNoteBook中dfSQL模塊來查詢DataFrame

SmartNoteBook是一款協作的、集成的、一站式的數據科學/分析環境,其內置的dfSQL方式可以快速實現利用SQL語句對DataFrame進行快速查詢。通過dfSQL,用戶可以實現利用簡單的SQL語句,對Pandas數據框、當前環境下的csv文件以及已經存在的df變量進行訪問,除了dfSQL方法也可實現對其它數據源的快速訪問,其基本用法如下:

1. 利用dfSQL從DataFrame變量中查詢:

在SmartNoteBook中新建的SQL單元格中,數據源我們選擇dfSQL,cars變量是前面我們已經讀取到變量空間中的DataFrame變量,則我們可以直接利用SQL語句對變量cars進行查詢,所查詢到的表結果保存為my_cars變量。

2. 利用dfSQL查詢環境中的csv文件:

在上述的SQL單元格中,數據源我們選擇dfSQL,Iris.csv是存在於本地的一個csv文件,我們可以通過dfSQL,利用SQL語句直接從環境中對其進行讀取,並選擇我們需要的變量進行聚合,重新保存在一個名為iris的DataFrame變量中。

3. 利用dfSQL進行聯合數據分析

在執行SQL語句時,有時為了查到複雜的信息我們往往需要對多表聯查或嵌套查詢,dfSQL通過在內存中加載保存變量,可以使得其邏輯更具可讀性:

上述SQL單元中,我們需要查詢每個地區Miles_per_Gallon、Cylinders、Acceleration均大於其地區均值的相關信息。我們可以分為兩步,先查出各個地區的相關變量均值,基於保存的df1變量,再從原表中取出滿足條件的信息並將其保存名為df2的DataFrame變量。

4. 利用SQL直接訪問數據源文件:

實際上在SmartNoteBook的SQL代碼模塊,其也支持選擇數據源,直接對遠程資料庫進行訪問並直接保存為DataFrame變量:

上述SQL單元,我們選擇了名為mysql 數據源的遠程數據倉庫,利用SQL語句直接讀取倉庫中的信息,並將其保存為名為my_data的DataFrame變量。

dfSQL具有更輕量化,集成優秀的特點,其對接外部數據源不需要再建立複雜的連結,而且可以直接實現對DataFrame變量和本地csv文件的訪問。後面執行的SQL查詢可以引用NoteBook中之前已執行的SQL查詢結果,就像我們寫複雜SQL中包含許多CTE(公共表表達式)一樣。用戶可以使用這種方式將複雜SQL按照邏輯進行拆分,使整個查詢過程更具可讀性。

關鍵字: