天天看點

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗

作者:外星人玩Python

前言

你有想過在 pandas 中直接使用 sql嗎?我知道許多小夥伴已經知道一些庫也可以做到這種體驗,不過他們的性能太差勁了(基于sqlite,或其他服務端資料庫)。

今天我要介紹另一個專用于資料分析的列式資料庫,性能是其他同體驗的庫的1000倍以上。可以無縫接入 pandas ,做到了性能與使用體驗同時提升。

這就是今天的主角,duckdb。

特點

duckdb 是一個單機資料庫,你大機率會用它與 sqlite 比較。

最明顯的差別就是,duckdb 是一個分析資料管理系統,而 sqlite 是一個事務型關系資料庫。

這意味着,如果你現在有一大堆資料處理任務,期間無須顧忌會有其他使用者插入新資料或删除資料。那麼 duckdb 就可以非常好應對這種場景。

對于我們這種 pandas 老使用者,duckdb 支援 pandas 的 dataFrame 通用底層格式(parquet/arrow等)上并行運作查詢,而且沒有單獨的導入步驟。這就是它能保持使用體驗的同時,大幅提升查詢性能的最大原因。

我們需要安裝這些庫

pip install pandas duckdb -U

先看一個例子,看看它是如何便捷與 dataframe 互動。

變量等于表名?

首先,導入今天需要用到的庫

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗

我們有一大堆銷售資料,加載其中一份資料看看:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗

此時,希望使用 sql 做一些資料查詢處理,你認為下面的 sql 簡單嗎?

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗
  • 直接使用 dataframe 的變量名作為表名查詢

這真的可以做到嗎?加上一點點 duckdb 的調用即可:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗
  • duckdb.query 做查詢
  • df,把查詢結果轉回 dataframe

也就是,可以直接使用目前環境下的變量作為表名。

我知道之前就有其他的庫可以做到這種體驗,但是必需強調,duckdb 是直接使用 dataframe 的記憶體資料(因為底層資料格式通用),是以,這個過程中的輸入和輸出資料的傳輸時間幾乎可以忽略不計。

并且,這個過程中,duckdb比 pandas 更快處理資料(多線程),并且記憶體使用量也比 pandas 要低得多。

特别在一些需要分組的資料處理任務上,就算隻使用單線程的 duckdb 也會比 pandas 的快兩倍。如果是過濾+分組+列投影,會存在 5-8倍 的差異。

如果加上表連接配接,則可能會到 15倍 的差異。

如果使用其他的一些 pandas 使用 sql 的庫,比如 pandasSql ,它比 duckdb 性能差距 1000倍 以上!

以上性能對比名額,均是 duckdb 官方說明,以後有機會實際操作對比。

性能方面,就"吹"到這裡。但是,我說 duckdb 有極緻的使用體驗,不僅僅隻是可以直接使用 dataframe 變量名作為表名寫 sql 。而是它提供了許多 sql 引擎沒有的優化文法體驗。

sql 的一些文法小痛點,duckdb 也在努力解決

現在我們需要加載所有的銷售資料檔案,如果使用 pandas 加載,則是這樣子:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗
  • 行3:得到 data 目錄下所有 csv 的檔案路徑
  • 行2:使用 pandas 加載

duckdb提供了許多友善的内置函數:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗
  • 行3:表名可以直接是本地的檔案。同時還支援通配符

預設情況下,duckdb 會把 csv 的第一行也加入到記錄中:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗

可以使用内置函數,通過參數設定一些加載規則:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗
  • 行4: read_csv_auto 可以設定具體加載檔案時的設定

不過,這個 header 參數其實是加載所有資料之後,再設定第一行為表頭。是以會看到實際資料仍然有一些表頭行:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗

我們可以直接在條件過濾中一步到位過濾掉無用的行:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗

此時,我們可以随時切換使用方式。

sql 中有一些語句在特定場景下,會顯得"無意義"。比如我希望查詢所有的列:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗

每次都寫一句 select * ,有點麻煩。在 duckdb 裡面,我們可以直接省略 select 語句。

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗

有時候,我們希望排除某幾列,可以這麼寫:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗
  • 行2:使用 * exclude ,裡面指定你希望排除的列名即可。注意,因為有一些列名有空格,你需要用雙引号或單引号包圍
這些功能都得益于它基于的列式資料儲存方式。

再看幾個小小的 sql 體驗改進。

别名用在過濾條件中:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗

自動識别分組列名:

python資料分析專用資料庫,與pandas結合,10倍提速+極緻體驗

它還有許多有意思的特性,如果希望我後續做更多的教學,評論區告訴我。

duckdb 是一個很有潛力的資料分析處理工具,結合 pandas 能否大幅提升我們的工作效率,值得大家嘗試使用。

不要忘記一鍵三連。你的點贊、收藏、關注,是我創作的動力。