python写sql语句_PandaSQL:一个让你能够通过SQL语句进行pandas的操作的python包

Pandas是近年来最好的数据操作库之一。它允许切片、分组、连接和执行任意数据转换。如果你熟练的使用SQL,那么这篇文章将介绍一种更直接、简单的使用Pandas处理大多数数据操作案例。

43a7d933c895d14327754cdfe2e0b1055baf07e6.jpeg?token=6b49879febd85c580e565cdac3abefe6

假设你对SQL非常的熟悉,或者你想有更可读的代码。或者您只是想在dataframe上运行一个特殊的SQL查询。或者,也许你来自R,想要一个sqldf的替代品。

这篇文章将介绍一种在pandas的dataframe中使用SQL的python包,并且使用一个不等链接的查询操作来介绍PandasSQL的使用方法。

不等连接(Non-equi join)

假设你必须连接两个dataframe。其中一个显示了我们对某些商品进行促销的时间段。第二个是事务Dataframe。我想知道促销活动推动的销售情况,也就是促销期间的销售情况。

我们可以通过联接项目列以及联接条件(TransactionDt≥StartDt和TransactionDt≤EndDt)来实现这一点。因为现在我们的连接条件也有大于号和小于号,这样的连接称为不等连接。在继续之前,一定要考虑如何在pandas中做这样的事情。

0b46f21fbe096b6358c2b8449e23b443eaf8ace7.jpeg?token=93166c0eb8f018d04637e87bf3dd1dd1

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)

cf1b9d16fdfaaf51ed051a061d44a7e9f11f7ab8.jpeg?token=0d6a80f70022f9b5206dfff88bc34398

8601a18b87d6277fce4c0537b9282c37e924fc7e.jpeg?token=fced74f94807edb672b2fdd5f3473e70

一旦我们有了数据,我们就可以通过合并列项上的数据来进行不等连接,然后根据所需条件进行过滤。

merged_df = pd.merge(offerDf,transactionDf,on='Item')pandas_solution = merged_df[(merged_df['TransactionDt']>=merged_df['StartDt']) & (merged_df['TransactionDt']<=merged_df['EndDt'])]

结果如下,正如我们所希望的:

ac4bd11373f08202045d69afdaebc8eaaa641b6e.jpeg?token=fad7e7ece2fb9fa5f5c24faa24a690cf

PandaSQL解决方案

Pandas解决方案很好,可以做我们想做的事情,但是我们也可以使用PandaSQL以一种可读性更强的方式完成同样的事情。

PandaSQL是什么?

PandaSQL为我们提供了在panda数据数据库上编写SQL的方法。因此,如果您已经编写了一些SQL查询,那么使用pandaSQL可能比将它们转换为panda语法更有意义。为了开始使用PandaSQL,我们简单地安装它:

pip install -U pandasql

安装了pandaSQL之后,我们可以通过创建pysqldf函数来使用它,该函数接受一个查询作为输入,并运行该查询来返回一个Pandas DF。不用担心语法,因为跟使用pandas差不多。

from pandasql import sqldfpysqldf = 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。索引已经自动为我们重置了,不像以前那样需要手动操作。

8d5494eef01f3a29732894a008358f365d607c97.jpeg?token=fe7f60f5b48a7967286f46f911a4575f

警告

虽然PandaSQL函数允许我们在我们的panda数据框架上运行SQL查询,并且在某些情况下是一个非常好的工具,但是它的性能不如纯panda语法。

8b82b9014a90f6039373c8dfa802801cb151ed7b.jpeg?token=be3ca788044aee3f0f3cde496f1ff665

a1ec08fa513d269766f11221c4eb81fc4316d847.jpeg?token=194bc821556e2c1e2e01d2ccd4968887

当我们用可读性更强的PandaSQL为pandas计时时,我们发现PandaSQL花费的时间大约是原生pandas的10倍。

结论

虽然PandaSQL库的性能不如本地的panda,但当我们想进行特别分析时,它是对我们的数据分析工具箱的一个很好的补充,而且对于那些更习惯使用SQL查询的人来说。

想要更深入地了解这篇文章的代码,请访问我的GitHub知识库,在那里你可以找到这篇文章和我所有的文章的代码。

github/MLWhiz/datascienceblogs/tree/master/pandasql

译者注:我一直在寻找能够使用sql处理pandas的dataframe的解决方案,pandasSQL在这这方面起到了很好的开端,虽然他的性能还不足以在生产环境中使用,但是我们再进行EDA和数据分析等一次性的操作的时候完全可以使用sql替代复杂的pandas的查询语法。所以如果你跟我一样,对SQL非常熟悉,并且厌倦了pandas的复杂语法,pandasSQL是一个很好的解决方案

作者:Rahul Agarwal

deephub翻译组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值