PandaSQL:一個讓你能夠通過SQL語句進行pandas的操作的python包

2021-01-10 deephub

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 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。索引已經自動為我們重置了,不像以前那樣需要手動操作。

警告

雖然PandaSQL函數允許我們在我們的panda數據框架上運行SQL查詢,並且在某些情況下是一個非常好的工具,但是它的性能不如純panda語法。

當我們用可讀性更強的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翻譯組

相關焦點

  • Pandas閃回咒!如何在Python中重寫SQL查詢?
    一些程式設計師只熟悉SQL中的數據操作,卻不熟悉Python中的數據操作,因此在完成項目時,我們不得不頻繁地在SQL和Python之間進行切換,導致了工作效率低下和生產能力下降。本文就教你一種方法,使用Pandas在Python中輕鬆重現SQL結果。
  • Python數據分析:pandas讀取和寫入數據
    繼續深入學習pandas相關操作,數據讀取寫入、分組、合併,轉換等等。前面一篇文章裡已經寫了關於描述性統計以及常用的基本操作。接下來的一段時間裡,我將陸續地去掌握並輸出。這篇文章是關於數據讀取與寫入的知識點。平時工作中,我們會接觸到不同的數據文件,比如很常見的excel文件(後綴名為xls和xlsx),csv、txt等文本文件,json文件以及sql文件等等。
  • 不會Pandas怎麼行
    Python 是開源的,它很棒,但是也無法避免開源的一些固有問題:很多包都在做(或者在嘗試做)同樣的事情。如果你是 Python 新手,那麼你很難知道某個特定任務的最佳包是哪個,你需要有經驗的人告訴你。有一個用於數據科學的包絕對是必需的,它就是 pandas。pandas 最有趣的地方在於裡面隱藏了很多包。
  • MyBatis Dynamic SQL 1.0.0,生成動態 SQL 語句的框架
    MyBatis Dynamic SQL 1.0.0 發布了,這個庫是生成動態 SQL 語句的框架。
  • SQL語句性能調整之ORACLE的執行計劃
    這個語句的優點就是它的缺點,這樣在用該方法查看執行時間較長的sql語句時,需要等待該語句執行成功後,才返回執行計劃,使優化的周期大大增長。  如果不想執行語句而只是想得到執行計劃可以採用:  Sql> set autotrace traceonly  這樣,就只會列出執行計劃,而不會真正的執行語句,大大減少了優化時間。
  • Python連接MySQL資料庫方法介紹(超詳細!手把手項目案例操作)
    ="select * from `student` " # SQL語句cur.execute(sql) # 執行SQL語句data = cur.fetchall() # 通過fetchall方法獲得數據for i in data[:2]: # 列印輸出前2條數據print (i)
  • 請確保你查詢mysql資料庫時,sql語句沒有這麼寫_手機網易網
    語句效率更高。所以大家在寫查詢的sql語句時為了讓語句執行效率高會讓語句能命中索引,或者新建合適的索引。  明明我sql語句where條件的欄位是符合索引,應該可以命中索引的,但是執行時卻沒有命中索引。  為什麼會這樣呢,是人性的……  額,串臺了,調回來。  要說明這個問題,大家先來比較一下下面的這兩個sql語句。  這兩個sql語句唯一的區別就是where條件中id對應的值一個加了引號,一個沒有加引號。
  • python3.8操作(插入,刪除)mysql/MariaDB資料庫
    01主題大家好,我是義縣遊學電子科技.今天來跟大家說一個工作中常用到的操作,python3.8操作MariaDB資料庫.因為MariaDB屬於mysql分支因此資料庫命令語句都是通用的非常方便.02環境python-3.8 ,64位mairadb-10.4.7,64位python包:mysql-connector-2.2.9
  • python數據分析——pandas導入數據合集
    導入pandas庫import pandas as pd1.導入csv\txt文件數據pd.read_csv()常用參數:filepath_or_buffer:文件路徑(必填,其他參數按需求填寫)sep:指定分隔符,默認逗號','。header:指定第幾行作為表頭。
  • 沒錯,純SQL查詢語句可以實現神經網絡
    選自Medium作者:Harisankar Haridas機器之心編譯參與:陳韻竹、思源我們熟知的SQL是一種資料庫查詢語句,它方便了開發者在大型數據中執行高效的操作。但本文從另一角度嵌套SQL查詢語句而構建了一個簡單的三層全連接網絡,雖然由於語句的嵌套過深而不能高效計算,但仍然是一個非常有意思的實驗。
  • Spark 3.0發布啦,改進SQL,棄Python 2,增強擴展,性能大幅提升
    Gregorian日曆;建立Spark自己的日期時間模式定義;為表插入引入ANSI存儲分配策略;在表插入中默認遵循ANSI存儲分配規則;添加一個SQLConf: spark.sql.ansi.enabled,用於開啟ANSI模式;支持聚合表達式的ANSI SQL過濾子句;支持ANSI SQL OVERLAY功能;支持ANSI嵌套方括號內的注釋;超出整數範圍時拋出異常;區間算術運算的溢出檢查;當無效字符串被轉換為數字類型時
  • Java最新SQL注入原因以及預防方案(易理解)
    SQL注入1.1 原理SQL注入是通過客戶端的輸入把SQL命令注入到一個應用的資料庫中,從而執行惡意的SQL語句。1.2 演示1.2.1 案例1有一個登錄框,需要 輸入用戶名和密碼 ,然後我們的密碼輸入 'or '123' = '123 這樣的。
  • SQL注入、XSS以及CSRF分別是什麼?
    本篇文章就來帶大家了解一下SQL注入、XSS和CSRF,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。SQL注入SQL注入是屬於注入式攻擊,這種攻擊是因為在項目中沒有將代碼與數據(比如用戶敏感數據)隔離,在讀取數據的時候,錯誤的將數據作為代碼的一部分執行而導致的。
  • 大數據分析工程師入門9-Spark SQL
    如果你想讓一個臨時視圖在所有session中相互傳遞並且可用,直到Spark 應用退出,你可以建立一個全局的臨時視圖,全局的臨時視圖存在於系統資料庫global_temp中,我們必須加上庫名去引用它。Case class 也可以是嵌套的或者包含像 Seq 或者 Array 這樣的複雜類型,這個 RDD 能夠被隱式轉換成一個 DataFrame 然後被註冊為一個表。
  • 如何通過一頓飯來說明NumPy與pandas的功用
    優化包括NumPy是在一個連續的內存塊中存儲數據,獨立於其他Python內置對象,如此便可以加速數據索引的速度。其次,NumPy調用了大量的用C語言編寫的算法庫,使得其可以直接操作內存,不必進行Python動態語言特性所含有的前期類型檢查工作,從而大大提高了運算速度。
  • 如何用python在工作中「偷懶」?
    ,遊戲掛機腳本,無非就是自動移動滑鼠,自動點擊,進行重複操作,所以,第一步就是如何控制滑鼠。思路:利用python xlrd包讀取excle文件,然後將文件內容存入一個列表中,再利用xlsxwriter將內容寫入到一個新的excel文件中。
  • MyBatis dynamic SQL 1.1.4 發布,生成動態 SQL 的框架
    MyBatis dynamic SQL 1.1.4 已發布,MyBatis Dynamic SQL 是生成動態 SQL 語句的框架,可把它看作是一個類型安全的 SQL 模板庫,它還支持 MyBatis3
  • PySpark源碼解析,用Python調用高效Scala接口,搞定大規模數據分析
    當通過 spark-submit 提交一個 PySpark 的 Python 腳本時,Driver 端會直接運行這個 Python 腳本,並從 Python 中啟動 JVM;而在 Python 中調用的 RDD 或者 DataFrame 的操作,會通過 Py4j 調用到 Java 的接口。
  • 詳解Python在資料庫測試中的應用
    rc = tb1.exec_sql("create table aa(c int);");#執行create語句且預期成功rc = tb1.exec_sql_failed("create table aa(c int);");#再次執行該語句,預期失敗k=((1,1),(1,1));#執行select且預期結果集與上面定義的k相同rc = tb1.exec_sql_with_result