Pandas是近年来最好的数据操作库之一。它允许切片、分组、连接和执行任意数据转换。如果你熟练的使用SQL,那么这篇文章将介绍一种更直接、简单的使用Pandas处理大多数数据操作案例。
假设你对SQL非常的熟悉,或者你想有更可读的代码。或者您只是想在dataframe上运行一个特殊的SQL查询。或者,也许你来自R,想要一个sqldf的替代品。
这篇文章将介绍一种在pandas的dataframe中使用SQL的python包,并且使用一个不等链接的查询操作来介绍PandasSQL的使用方法。
不等连接(Non-equi join)
假设你必须连接两个dataframe。其中一个显示了我们对某些商品进行促销的时间段。第二个是事务Dataframe。我想知道促销活动推动的销售情况,也就是促销期间的销售情况。
我们可以通过联接项目列以及联接条件(TransactionDt≥StartDt和TransactionDt≤EndDt)来实现这一点。因为现在我们的连接条件也有大于号和小于号,这样的连接称为不等连接。在继续之前,一定要考虑如何在pandas中做这样的事情。
pandas的解决方案
那么在pandas身上该怎么做呢?pandas肯定可以解决这个问题,尽管我认为它的可读性不够。
让我们从生成一些要处理的随机数据开始。
import pandas as pd
import random
import datetime
def random_dt_bw(start_date,end_date):
days_between = (end_date - start_date).days
random_num_days = random.randrange(days_between)
random_dt = start_date + datetime.timedelta(days=random_num_days)
return random_dt
def generate_data(n=1000):
items = [f"i_{x}" for x in range(n)]
start_dates = [random_dt_bw(datetime.date(2020,1,1),datetime.date(2020,9,1)) for x in range(n)]
end_dates = [x + datetime.timedelta(days=random.randint(1,10)) for x in start_dates]
offerDf = pd.DataFrame({"Item":items,
"StartDt":start_dates,
"EndDt":end_dates})
transaction_items = [f"i_{random.randint(0,n)}" for x in range(5*n)]
transaction_dt = [random_dt_bw(datetime.date(2020,1,1),datetime.date(2020,9,1)) for x in range(5*n)]
sales_amt = [random.randint(0,1000) for x in range(5*n)]
transactionDf = pd.DataFrame({"Item":transaction_items,"TransactionDt":transaction_dt,"Sales":sales_amt})
return offerDf,transactionDf
您不需要担心上面的随机数据生成代码。只要知道我们的随机数据是什么样子就可以了:
offerDf,transactionDf = generate_data(n=100000)
一旦我们有了数据,我们就可以通过合并列项上的数据来进行不等连接,然后根据所需条件进行过滤。
merged_df = pd.merge(offerDf,transactionDf,on='Item')pandas_solution = merged_df[(merged_df['TransactionDt']>=merged_df['StartDt']) &
(merged_df['TransactionDt']<=merged_df['EndDt'])]
结果如下,正如我们所希望的:
PandaSQL解决方案
Pandas解决方案很好,可以做我们想做的事情,但是我们也可以使用PandaSQL以一种可读性更强的方式完成同样的事情。
PandaSQL是什么?
PandaSQL为我们提供了在panda数据数据库上编写SQL的方法。因此,如果您已经编写了一些SQL查询,那么使用pandaSQL可能比将它们转换为panda语法更有意义。为了开始使用PandaSQL,我们简单地安装它:
pip install -U pandasql
安装了pandaSQL之后,我们可以通过创建pysqldf函数来使用它,该函数接受一个查询作为输入,并运行该查询来返回一个Pandas DF。不用担心语法,因为跟使用pandas差不多。
from pandasql import sqldf
pysqldf = lambda q: sqldf(q, globals())
现在,我们可以使用这个函数在我们的pandas dataframe上运行任何SQL查询。下面是不等连接,我们希望使用可读性更强的SQL格式。
q = """
SELECT A.*,B.TransactionDt,B.Sales
FROM
offerDf A
INNER JOIN
transactionDf B
ON
A.Item = B.Item AND
A.StartDt <= B.TransactionDt AND
A.EndDt >= B.TransactionDt;
"""
pandaSQL_solution = pysqldf(q)
结果是一个我们所期望的panda Dataframe。索引已经自动为我们重置了,不像以前那样需要手动操作。
警告
虽然PandaSQL函数允许我们在我们的panda数据框架上运行SQL查询,并且在某些情况下是一个非常好的工具,但是它的性能不如纯panda语法。
当我们用可读性更强的PandaSQL为pandas计时时,我们发现PandaSQL花费的时间大约是原生pandas的10倍。
结论
虽然PandaSQL库的性能不如本地的panda,但当我们想进行特别分析时,它是对我们的数据分析工具箱的一个很好的补充,而且对于那些更习惯使用SQL查询的人来说。
想要更深入地了解这篇文章的代码,请访问我的GitHub知识库,在那里你可以找到这篇文章和我所有的文章的代码。
https://github.com/MLWhiz/data_science_blogs/tree/master/pandasql
译者注:我一直在寻找能够使用sql处理pandas的dataframe的解决方案,pandasSQL在这这方面起到了很好的开端,虽然他的性能还不足以在生产环境中使用,但是我们再进行EDA和数据分析等一次性的操作的时候完全可以使用sql替代复杂的pandas的查询语法。所以如果你跟我一样,对SQL非常熟悉,并且厌倦了pandas的复杂语法,pandasSQL是一个很好的解决方案
作者:Rahul Agarwal
deephub翻译组
转载:https://blog.csdn.net/m0_46510245/article/details/108293342