结合使用 Pandas 和 SQL 进行数据分析
在本教程中,我们将探讨何时以及如何将 SQL 功能集成到 Pandas 框架中,以及它的局限性。
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 执行相同的操作。
将 Pandas 与 Python 结合使用:
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 Notebook 中执行前面的 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 样式的语法可能更自然。
执行 JOIN
连接是一种基于公共列组合来自多个源的数据的强大方法,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()
函数实现相同的结果,指定 on 匹配列并指定 how='left'
执行左连接。 Pandas 可以轻松地合并多个列,并提供指定连接类型的灵活性。但是,在处理较大的表或执行更复杂的连接时,SQL 样式的连接语法可能更具可读性。
自定义查询
在此示例中,我们检索基于“防御”的前 5 条记录,并按降序排序。
熊猫SQL:
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 工作的人来说可以更加 Pythonic 和集成。
您可以在以下 Jupyter Notebook 中查看此处显示的所有代码