译者 | 布加迪
审校 | 重楼
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