如果您考虑 Pandas DataFrame 的结构和 SQL 数据库中表的结构,它们的结构非常相似。它们都由数据点或值组成,每一行都有一个唯一的索引,每一列都有一个唯一的名称。因此,SQL 允许您快速访问您正在处理的任何项目所需的特定信息。但是,可以使用 Pandas 进行非常相似的查询!在这篇博文中,我将向您展示如何做到这一点,同时解释您需要哪个库来实现它。
在使用 SQL 时,获取我们需要的信息称为查询数据。在 Pandas 中,有一个内置的查询方法可以让您做完全相同的事情,称为.query()。这既节省了时间,又使代码中的查询更加连贯,因为您不必使用切片语法。例如,使用.query()方法在 Pandas 中查询数据的简短示例是:
query_df = df.query("Col_1 > Col_2")
否则,如果您不使用此方法获取数据而是使用切片语法,则它看起来像这样:
query_df = df[df[df['Col_1'] > df['Col_2']]]
就像我说的,.query()方法让你的代码看起来更专业、更高效。我要注意的一件重要事情是,如果/当您决定在 Pandas 查询中使用“and”或“or”时,您实际上不能使用“and”或“or”——您必须使用符号代替“和”(&)和“或”(|)。下面是一个使用“&”来帮助澄清的例子:
query_df = df.query("Col_1 > Col_2 & Col_2 <= Col_3")
众所周知,使用 SQL 和/或其所有变体的能力是市场上数据科学家最需要的工作技能之一——即使在大流行期间也是如此。幸运的是,Python 中有一个名为pandasql的库,它允许您编写 SQL 风格的语法来从 Pandas DataFrames 收集数据!这对于想要练习 SQL 技能的有抱负的数据科学家和习惯于使用 SQL 样式语法收集数据的经验丰富的数据科学家来说都非常有用。要将其安装到您的计算机上,只需使用 !pip install:
pip install pandasql
然后,要将其导入您的笔记本,您需要从pandasql导入一个sqldf对象:
from pandasql import sqldf
导入所有内容后,最好编写一个快速的 lambda 函数,以便更轻松地编写查询。这样做的原因是您不必在每次使用对象时都传入全局变量。以下是我教过并成功使用的 lambda 函数:
pysqldf = lambda q: sqldf(q, globals())
现在,每当您将查询传递到pysqldf 时,全局变量将在 lambda 中传递,这样您就不必为使用的每个对象一遍又一遍地执行此操作。
现在您已设置好一切并准备就绪,您可以使用与 SQL 相同的语法在 DataFrame 中查询数据!这是一个例子——这个查询将从 df 返回前 10 个名称:
q = """SELECT Name FROM df LIMIT 10;""" names = pysqldf(q) names
您查询的复杂性取决于您的需求和您作为数据科学家的技能。因此,如果您习惯于使用 SQL 风格的语法,或者希望提高您的 SQL 语法技能,使用pandasql可能是继续组织数据和练习技能的好方法。
Demo
merge_data_sql = sqldf(""" SELECT * FROM apm_data_df LEFT OUTER JOIN pingips_data_df ON apm_data_df.pingip = pingips_data_df.pingip WHERE apm_data_df IS null """) merge_result = sqldf(merge_data_sql, globals())
SQL(Structured Query Language, 结构化查询语言)是用于访问和处理数据库的标准的计算机语言,也是数据清洗的神器。
日常的数据统计分析工作中,80%的时间是在做数据清洗,只有20%的时间在优化模型、分析统计结果等。数据清洗的工作的重要性不言而喻,今天先简单介绍下数据清洗中最重要的工具--SQL。
通过sqldf包,可直接在R中的数据框(data.frame)(类似数据库中的表)上进行SQL操作,R中数据清洗常用的dplyr包的许多函数操作也是将相应的命令转化为SQL语句来执行。sqldf包支持SQLite(默认), H2,MySQL及PostgreSQL作为后台来执行SQL语句。SQLite及H2是两个无服务器端,无需配置的轻量级数据库管理系统,在R中安装好并加载sqldf包就可以直接使用SQLite数据库来操作数据,H2同时还需要安装并加载RH2包即可使用(MySQL和PostgreSQL需要繁琐的服务器端客户端的配置)。SQLite灵活轻便,应用非常广泛,集成到了许多IOS及Android的app中。SQLite 没有一个单独的用于存储日期和/或时间的存储类,但 SQLite 能够把日期和时间存储为文本或数值类型(在用SQLite处理日期数据的时候要非常小心,以后再细说)。
主要介绍使用SQLite为后台,通过sqldf中执行SQL语句
library(sqldf)
df2 <- sqldf('select * from df',drv = 'SQLite')
##这里的drv不写默认就是SQLite。选择df数据库所有变量(* 代表所有变量)
> df1 <- head(warpbreaks, 5)
> df2 <- sqldf('select * from warpbreaks limit 5;')
> identical(df1, df2)
[1] TRUE
> data(farms, package = 'MASS')
> df1 <- subset(farms, Manag %in% c('SF', 'BF'))
> df2 <- sqldf("select * from farms where Manag in ('SF', 'BF')")
> row.names(df1) <- NULL
> identical(df1, df2)
[1] TRUE
> df1 <- subset(warpbreaks, breaks >= 20 & breaks <= 30)
> df2 <- sqldf('select * from warpbreaks where breaks between 20 and 30;')
> row.names(df1) <- NULL
> identical(df1, df2)
[1] TRUE
> df1 <- subset(farms, Mois == 'M1')
> df2 <- sqldf('select * from farms where Mois = "M1"', row.names = T)
> identical(df1, df2)
[1] TRUE
> df1 <- subset(farms, Mois == 'M1')
> df2 <- subset(farms, Mois == 'M2')
> df3 <- sqldf('select * from farms where Mois = "M1"', row.names = T)
> df4 <- sqldf('select * from farms where Mois = "M2"', row.names = T)
> df12 <- rbind(df1, df2)
> df34 <- sqldf('select * from df3 union all select * from df4', row.names = T)
> identical(df12, df34)
[1] TRUE
> df1 <- aggregate(iris[1:2], iris[5], mean)
> df2 <- sqldf('select Species, avg("Sepal.Length") as "Sepal.Length",
+ avg("Sepal.Width") as "Sepal.Width" from iris group by Species;')
> all.equal(df1, df2)
[1] TRUE
> df1 <- head(warpbreaks[order(warpbreaks$breaks, decreasing = T), ], 3)
> df2 <- sqldf('select * from warpbreaks order by breaks desc limit 3;')
> row.names(df1) <- NULL
> identical(df1, df2)
[1] TRUE