SQL,或結構化查找語言,是一種用來存取、抽取、整理及探索存放在關係型數據庫中的數據的程式設計語言。pandas是一個Python開源庫,特別為數據操作和分析設計。
在這個教程中,我們將討論何時以及如何使用SQL功能在pandas框架內(以及何時不能使用)。此外,我們將查看各種實例來實現這種方法,並將結果與純粹的pandas代碼進行比較。
何時在pandas中使用SQL?
給出导言中的定義,那麼何時應該要把SQL和pandas結合使用,後者不是一個全集式的數據分析工具包嗎?
答案是在某些情況下,特別是對於複雜的程序,SQL查詢看起來比對應的pandas代碼簡單和易於閱讀,這對於最初用SQL處理數據然後才學習pandas的人尤其正確。
如果你需要對pandas有更多的培訓,你可以查看我們的使用pandas進行數據操作課程和Python中的DataFrames教程。
要看SQL的可讀性,假設我們有一個叫做penguins
的表(dataframe),其中包含了有关企鵝的各种信息(稍后在這個教程中我們會使用這個表)。要提取所有独特種類的企鵝,這些企鵝是男性且胸鰭長度超過210毫米,我們在pandas中需要以下的代碼:
penguins[(penguins['sex'] == 'Male') & (penguins['flipper_length_mm'] > 210)]['species'].unique()
相反地,要使用SQL取得同樣的信息,我們會運行以下的代碼:
SELECT DISTINCT species FROM penguins WHERE sex = 'Male' AND flipper_length_mm > 210
第二段用SQL寫的代碼,几乎就像是自然英语句子,因此遠比pandas的代碼直觀。我們可以進一步通過將它分成多行來提高可讀性:
SELECT DISTINCT species FROM penguins WHERE sex = 'Male' AND flipper_length_mm > 210
現在我們已經確定使用SQL對於pandas的優點,讓我們看看我們如何技術上將它們結合在一起。
如何使用pandasql
pandasql Python庫允許通過運行SQL命令來查询pandas dataframe,而無需連接任何SQL服務器。在內部,它使用SQLite語法,自動檢測到任何pandas dataframe,並將其視為一般的SQL表。
設定你的環境
首先,我們需要安装pandasql:
pip install pandasql
然後,我們導入所需的包:
from pandasql import sqldf import pandas as pd
上述我們直接從 pandasql 引入了 sqldf
函數,這實際上是該函式庫唯一有意義的函數。如其名稱所示,它用於使用 SQL 語法查詢數據框。除了這個函數之外,pandasql 還包含兩個簡單的內建模組數據集,可以使用說明性函數 load_births()
和 load_meat()
加載。
pandasql 語法
sqldf
函數的語法非常簡單:
sqldf(query, env=None)
在這裡,query
是一個必需的參數,用於接收 SQL 查詢字串,而 env
則是一個可選(且很少使用)的參數,可以是 locals()
或 globals()
,這樣 sqldf
便能夠訪問 Python 環境中對應的變量集合。
sqldf
函數返回查詢結果作為 pandas 數據框。
何時可以使用 pandasql
pandasql 函式庫允許使用數據查詢語言(DQL),這是 SQL 的子集之一。換句話說,使用 pandasql,我們可以在數據庫中存儲的數據上運行查詢,從中提取必要的信息。尤其是我們可以訪問、提取、過濾、排序、分組、聯接、聚合數據,並對其進行數學或邏輯操作。
何時不能使用 pandasql
pandasql 不允許使用 SQL 的其他子集,除了 DQL。這意味著我們無法應用 pandasql 來修改(更新、截斷、插入等)表或更改(更新、刪除或插入)表中的數據。
此外,由於這個函式庫是基於SQL語法,我們應該注意SQLite的已知怪癖。
pandasql的使用示例
現在,我們將更詳細地了解如何使用pandasql
的sqldf
函數在pandas數據框上運行SQL查詢。為了有一些數據進行練習,我們來加載seaborn庫的一個內建數據集—penguins
:
import seaborn as sns penguins = sns.load_dataset('penguins') print(penguins.head())
輸出:
species island bill_length_mm bill_depth_mm flipper_length_mm \ 0 Adelie Torgersen 39.1 18.7 181.0 1 Adelie Torgersen 39.5 17.4 186.0 2 Adelie Torgersen 40.3 18.0 195.0 3 Adelie Torgersen NaN NaN NaN 4 Adelie Torgersen 36.7 19.3 193.0 body_mass_g sex 0 3750.0 Male 1 3800.0 Female 2 3250.0 Female 3 NaN NaN 4 3450.0 Female
如果您需要刷新您的SQL技能,我們的SQL基礎知識技能軌道是一個很好的參考點。
使用pandasql提取數據
print(sqldf('''SELECT species, island FROM penguins LIMIT 5'''))
輸出:
species island 0 Adelie Torgersen 1 Adelie Torgersen 2 Adelie Torgersen 3 Adelie Torgersen 4 Adelie Torgersen
在上面的例子中,我們從penguins
數據框中提取了關於前五隻企鵝的種類和地理信息。請注意,運行sqldf
函數將返回一個pandas數據框:
print(type(sqldf('''SELECT species, island FROM penguins LIMIT 5''')))
輸出:
<class 'pandas.core.frame.DataFrame'>
在純粹的pandas中,它將是:
print(penguins[['species', 'island']].head())
輸出:
species island 0 Adelie Torgersen 1 Adelie Torgersen 2 Adelie Torgersen 3 Adelie Torgersen 4 Adelie Torgersen
另一個例子是從列中提取唯一值:
print(sqldf('''SELECT DISTINCT species FROM penguins'''))
輸出:
species 0 Adelie 1 Chinstrap 2 Gentoo
在pandas中,它將是:
print(penguins['species'].unique())
輸出:
['Adelie' 'Chinstrap' 'Gentoo']
使用pandasql排序數據
print(sqldf('''SELECT body_mass_g FROM penguins ORDER BY body_mass_g DESC LIMIT 5'''))
輸出:
body_mass_g 0 6300.0 1 6050.0 2 6000.0 3 6000.0 4 5950.0
在上面的例子中,我們按體重降序排列了企鵝,並顯示了體重的前五個值。
在 pandas 中,它會是:
print(penguins['body_mass_g'].sort_values(ascending=False, ignore_index=True).head())
輸出:
0 6300.0 1 6050.0 2 6000.0 3 6000.0 4 5950.0 Name: body_mass_g, dtype: float64
使用 pandasql 篩選資料
讓我們試著用章節中提到的同一個例子:提取性別為男性且蹼長超過 210 毫米的企鵝獨特品種:
print(sqldf('''SELECT DISTINCT species FROM penguins WHERE sex = 'Male' AND flipper_length_mm > 210'''))
輸出:
species 0 Chinstrap 1 Gentoo
在上述情況下,我們根據兩個條件過濾資料:sex = 'Male'
和 flipper_length_mm > 210
。
pandas 中相同的代碼會顯得有點複雜:
print(penguins[(penguins['sex'] == 'Male') & (penguins['flipper_length_mm'] > 210)]['species'].unique())
輸出:
['Chinstrap' 'Gentoo']
使用 pandasql 對資料進行分組和聚合
現在,讓我們對資料進行分組和聚合,以找出數據框中每種品種的最長嘴長:
print(sqldf('''SELECT species, MAX(bill_length_mm) FROM penguins GROUP BY species'''))
輸出:
species MAX(bill_length_mm) 0 Adelie 46.0 1 Chinstrap 58.0 2 Gentoo 59.6
pandas 中相同的代碼:
print(penguins[['species', 'bill_length_mm']].groupby('species', as_index=False).max())
輸出:
species bill_length_mm 0 Adelie 46.0 1 Chinstrap 58.0 2 Gentoo 59.6
使用 pandasql 進行數學運算
使用 pandasql,我們可以輕鬆對資料進行數學或邏輯運算。假設我們想計算每隻企鵝的嘴長與深度的比例,並顯示這項測量值的 top 5:
print(sqldf('''SELECT bill_length_mm / bill_depth_mm AS length_to_depth FROM penguins ORDER BY length_to_depth DESC LIMIT 5'''))
輸出:
length_to_depth 0 3.612676 1 3.510490 2 3.505882 3 3.492424 4 3.458599
請注意,這次我們使用了別名 length_to_depth
來表示比例值的列。否則,我們將得到一個名稱可怕的列 bill_length_mm / bill_depth_mm
。
在 pandas 中,我們需要先創建一個含有比例值的新列:
penguins['length_to_depth'] = penguins['bill_length_mm'] / penguins['bill_depth_mm'] print(penguins['length_to_depth'].sort_values(ascending=False, ignore_index=True).head())
輸出:
0 3.612676 1 3.510490 2 3.505882 3 3.492424 4 3.458599 Name: length_to_depth, dtype: float64
結論
總結來說,在本教程中,我們探索了為什麼以及何時可以結合 SQL 的功能來提升 pandas 的代碼效率。我們討論了如何設置和使用 pandasql 庫來達到這個目的,並分析了該套件的限制。最後,我們考慮了多個 pandasql 實際應用的流行範例,並在每種情況下將其代碼與 pandas 進行了比較。
現在,您已擁有將 SQL 應用於 pandas 的一切所需知識,可在實際項目中應用。DataLab 是一個非常好的練習場所,這是 DataCamp 的 AI 支持數據筆記本,具有出色的 SQL 支持。
Source:
https://www.datacamp.com/tutorial/how-to-use-sql-in-pandas-using-pandasql-queries