譯者 | 布加迪
審校 | 重樓
SQL(即結構化查詢語言)長期以來一直是數據管理的首選工具,但有時它不盡如人意,需要Python等工具的強大功能和靈活性。Python是一種通用的多用途編程語言,擅長訪問、提取、處理和探索關系數據庫中的數據。Python中的開源庫Pandas專門用于數據操縱和分析。
我們在本教程中將探討何時以及如何將SQL功能整合到Pandas框架中,并探討其局限性。
現在你可能想知道的主要問題是……
為什么兩者都使用?
原因在于可讀性和熟悉度:在某些情況下,尤其是在復雜的工作流中,SQL查詢可以比等效的Pandas代碼更清晰、更容易閱讀。對于那些在改用Pandas之前開始用SQL處理數據的人來說,尤其如此。
此外,由于大多數數據源自數據庫,SQL作為這些數據庫的原生語言,提供了天然的優勢。這就是為什么許多數據專業人員(特別是數據科學家)經常在同一數據管道中整合SQL和Python(具體是Pandas),以發揮兩者之所長。
要查看實際的SQL可讀性,不妨使用下面的pokemon gen1 pokedex csv文件。
設想我們希望按“Total”列按升序對DataFrame進行排序,并顯示前5個。現在我們可以比較如何使用Pandas和SQL執行相同的操作。
結合使用Python和Pandas:
data[["#", "Name", "Total"]].sort_values(by="Total", ascending=True).head(5)
使用SQL:
SELECT
"#",
Name,
Total
FROM data
ORDER BY Total
LIMIT 5
你看到兩者有多不同了吧?但是…我們如何在我們的工作環境中將這兩種語言與Python結合起來?
解決辦法就是使用PandaSQL!
使用PandaSQL
Pandas是一個功能強大的開源數據分析和操縱python庫。PandaSQL允許用戶使用SQL語法來查詢Pandas DataFrame。對于剛接觸Pandas的人來說,PandaSQL試圖使數據操縱和清理讓人更熟悉。你可以使用PandaSQL利用SQL語法查詢Pandas DataFrame。
不妨看一看。
首先,我們需要安裝PandaSQL:
pip install pandasql
然后與往常一樣,我們導入所需的軟件包:
from pandasql import sqldf
在這里,我們直接從PandaSQL導入sqldf函數,這實際上是該庫的核心特性。顧名思義,sqldf允許你使用SQL語法查詢DataFrame。
sqldf (query_string env =None)
在此上下文中,query_string是必需的參數,它接受字符串格式的SQL查詢。env參數是可選的,很少使用,可以設置為locals()或globals(),使sqldf能夠訪問Python環境中指定范圍內的變量。
除了這個函數外,PandaSQL還包括兩個基本的內置數據集,它們可以用簡單的函數load_births()和load_meat()來加載。這樣,你就可以使用內置的一些虛擬數據。
現在,如果我們想在Python Jupyter筆記本中執行前面的SQL查詢,它將像下面這樣:
from pandasql import sqldf
import pandas as pd
sqldf('''
SELECT "#", Name, Total
FROM data
ORDER BY Total
LIMIT 5''')
sqldf函數將查詢結果作為Pandas DataFrame返回。
我們應該什么時候使用它?
pandasql庫支持使用SQL的數據查詢語言(DQL)進行數據操縱,提供了一種熟悉的、基于SQL的方法與Pandas DataFrame中的數據進行交互。
借助pandasql,你可以直接對數據集執行查詢,從而實現高效的數據檢索、過濾、排序、分組、連接和聚合。
此外,它支持執行數學和邏輯操作,使其成為精通SQL的用戶使用Python處理數據的一種強大工具。
PandaSQL僅限于SQL的數據查詢語言(DQL)子集,這意味著它不支持修改表,也不支持UPDATE、INSERT或DELETE等數據操作。
此外,由于PandaSQL依賴SQL語法,具體是SQLite,因此必須注意可能影響查詢行為的SQLite特有的怪癖。
比較PandasSQL和SQL
本節演示如何使用PandaSQL和Pandas來實現相似的結果,并提供橫向比較以突出它們各自的方法。
- 生成多個表
不妨從更龐大的數據集生成數據子集,創建類型、特性等表。使用PandaSQL,我們可以指定SQL查詢來選擇特定的列,從而易于提取我們想要的確切數據。
使用PandaSQL:
types = sqldf('''
SELECT "#", Name, "Type 1", "Type 2"
FROM data''')
legendaries = sqldf('''
SELECT "#", Name, Legendary
FROM data''')
generations = sqldf('''
SELECT "#", Name, Generation
FROM data''')
features = sqldf('''
SELECT "#", Name, Total, HP, Attack, Defense, "Sp. Atk", "Sp. Def","Speed"
FROM data''')
這里,PandaSQL支持一種干凈的、基于SQL的選擇語法,對于熟悉關系數據庫的用戶來說,這種語法非常直觀。如果數據選擇涉及復雜的條件或SQL函數,它特別有用。
使用純Python:
# Selecting columns for types
types = data[['#', 'Name', 'Type 1', 'Type 2']]
# Selecting columns for legendaries
legendaries = data[['#','Name', 'Legendary']]
# Selecting columns for generations
generations = data[['#','Name', 'Generation']]
# Selecting columns for features
features = data[['#','Name', 'Total', 'HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed']]
在純Python中,我們只需在方括號內指定列名即可獲得相同的結果。雖然這對于直接的列選擇很高效,但是對于較復雜的過濾或分組條件,可讀性可能會降低,在這種條件下,SQL風格的語法可能更自然。
- 執行連接
連接是基于公共列組合來自多個數據源的數據的強大方法,PandaSQL和Pandas都支持此功能。
首先,PandaSQL:
types_features = sqldf('''
SELECT
t1.*,
t2.Total,
t2.HP,
t2.Attack,
t2.Defense,
t2."Sp. Atk",
t2."Sp. Def",
t2."Speed"
FROM types AS t1
LEFT JOIN features AS t2
ON t1."#" = t2."#"
AND t1.Name = t2.Name
’’’)
使用SQL,這個LEFT JOIN基于#和Name列中的匹配值組合類型和特性。這種方法對于SQL用戶來說很簡單,用于從多個表選擇特定列和組合數據的語法很清晰。
在純Python中:
# Performing a left join between `types` and `features` on the columns "#" and "Name"
types_features = types.merge(
features,
on=['#', 'Name'],
how='left'
)
types_features
在純Python中,我們使用merge()函數完成相同的結果,指定匹配列以及how='left'來執行左連接。Pandas使合并多列變得很容易,并在指定連接類型方面提供了靈活性。然而,在處理較大的表或執行較復雜的連接時,SQL類型的連接語法更具可讀性。
- 自定義查詢
在該示例中,我們基于“Defense”按降序檢索前5條記錄。
PandaSQL:
top_5_defense = sqldf('''
SELECT
Name, Defense
FROM features
ORDER BY Defense DESC
LIMIT 5
''')
SQL查詢按Defense列按降序對特性進行排序,并將結果限制為前5個條目。這種方法很直接,特別是對于SQL用戶,ORDER BY和LIMIT關鍵字明確了查詢的作用。
在純Python中:
top_5_defense = features[['Name', 'Defense']].sort_values(by='Defense', ascending=False).head(5)
僅使用Python,我們使用sort_values()按Defense排序,然后使用head(5)來限制輸出,從而獲得相同的結果。Pandas為排序和選擇記錄提供了一種靈活而直觀的語法,不過經常處理數據庫的人可能更熟悉SQL方法。
結論
我們在本教程中研究了如何以及何時結合SQL功能與Pandas有助于生成更干凈、更高效的代碼。我們介紹了PandaSQL庫的設置和使用以及局限性,并演示了幾個流行的示例,以比較PandaSQL代碼與等效的Pandas Python代碼。
通過比較這些方法,你可以看到,PandaSQL對于熟悉SQL的用戶或具有復雜查詢的場景很有幫助,而原生Pandas代碼對于習慣于使用Python的用戶來說可能更符合Python、更有機整合。
你可以在下面的Jupyter Notebook中查看本文顯示的所有代碼:https://www.kdnuggets.com/using-pandas-and-sql-together-for-data-analysis。
原文標題:Using Pandas and SQL Together for Data Analysis,作者:Josep Ferrer