跳至内容
SQL
Python

如何在 pandas 中使用 SQL:借助 pandasql 执行查询

在 pandas 中释放 SQL 的强大能力,了解何时以及如何使用 pandasql 库在 pandas 中执行 SQL 查询,实现无缝集成。
Elena Kosourova's photo
Elena Kosourova
已更新 · 8分钟 阅读

使用 AI 探索

ChatGPTClaudePerplexity

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。

在本教程中,我们将讨论在 pandas 框架中何时以及如何(以及何时不能)使用 SQL 功能。此外,我们还将查看多种实现该方法的示例,并将结果与等效的纯 pandas 代码进行比较。

为何在 pandas 中使用 SQL?

当 pandas 已经是一个面向数据分析的全能型包时,为什么还要将它与 SQL 结合使用?

答案是,在某些情况下,尤其是对于复杂程序,SQL 查询相比相应的 pandas 代码更直观、可读性更强。对于先用 SQL 处理数据、后来才学习 pandas 的人来说,这一点尤为明显。

为了直观感受 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 代码几乎像自然英语句子一样,因此更直观。我们还可以把它分成多行以进一步提升可读性:

SELECT DISTINCT species
  FROM penguins 
 WHERE sex = 'Male' 
   AND flipper_length_mm > 210

既然我们已经认识到了在 pandas 中使用 SQL 的优势,接下来看看如何在技术上将二者结合。

如何使用 pandasql

pandasql 是一个 Python 库,它允许您在无需连接任何 SQL 服务器的情况下,通过运行 SQL 命令来查询 pandas 的 dataframe。在底层,它使用 SQLite 语法,可自动检测任意 pandas dataframe,并将其视作常规的 SQL 表。

环境准备

首先,安装 pandasql:

pip install pandasql

然后,导入所需的包:

from pandasql import sqldf
import pandas as pd

如上,我们直接从 pandasql 导入了 sqldf() 函数,它几乎是该库唯一有意义的函数。顾名思义,它用于以 SQL 语法查询 dataframe。除此之外,pandasql 还带有两个简单的内置数据集,可通过不言自明的函数 load_births() 和 load_meat() 加载。

pandasql 语法

sqldf() 函数的语法非常简单:

sqldf(query, env=None)

其中,query 是必需参数,接收字符串形式的 SQL 查询;env 是可选参数(且很少有用),可为 locals() 或 globals(),允许 sqldf() 访问您 Python 环境中的相应变量集合。

sqldf() 函数会将查询结果以 pandas dataframe 的形式返回。

可以使用 pandasql 的场景

pandasql 允许使用 SQL 的数据查询语言(DQL)来处理数据。换句话说,利用 pandasql,我们可以对存储在数据库中的数据运行查询,从中检索所需信息。具体而言,我们可以对数据进行访问、提取、筛选、排序、分组、连接、聚合,并执行数学或逻辑运算。

不适用 pandasql 的场景

除了 DQL 之外,pandasql 不支持使用 SQL 的其他子集。这意味着我们无法使用 pandasql 去修改(update、truncate、insert 等)表,或更改表中的数据(update、delete 或 insert)。

此外,由于该库基于 SQL 语法,我们还应注意 SQLite 的一些已知特性。

pandasql 的使用示例

现在,我们将更细致地了解如何使用 pandasql 的 sqldf() 函数在 pandas 的 dataframe 上运行 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 Fundamentals 技能路径是不错的参考。

使用 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 dataframe 中提取了前五只企鹅的物种和所在岛屿信息。注意,运行 sqldf() 会返回一个 pandas 的 dataframe:

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 筛选数据

让我们尝试在“为何在 pandas 中使用 SQL”一节中提到的同一示例:提取“性别为雄性且鳍长超过 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 分组与聚合

现在,我们进行分组与聚合,找出每个物种在 dataframe 中最长的喙长度:

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,我们可以方便地对数据执行数学或逻辑运算。假设我们要计算每只企鹅的“喙长与喙深之比”,并展示该指标的前五个值:

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 支持。

主题
SQL
Python

拓展您的技能

课程

SQL 中的数据处理

4 小时
338.4K
掌握复杂的 SQL 查询,解答各种数据科学问题,并在 PostgreSQL 中准备稳健的数据集用于分析。
查看详情开始课程

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。
查看更多