2012-01-24 87 views
141

我最近遇到了pandas python庫,根據this benchmark執行非常快速的內存合併。它甚至比R中的data.table包快(我選擇用於分析的語言)。爲什麼熊貓比Python中的data.table合併更快?

爲什麼pandasdata.table快得多?是因爲python對R的固有速度優勢,還是存在一些我不知道的折衷?有沒有辦法在data.table中執行內部和外部連接,而不使用merge(X, Y, all=FALSE)merge(X, Y, all=TRUE)

Comparison

這裏的R code並用於標杆Python code的各種包。

+0

我的假設:因爲data.table是基於data.frame和data.frames是緩慢的。我認爲大部分熊貓合併代碼都在Cython中。 –

+10

@JoshuaUlrich:IIRC'data.table'只是繼承自'data.frame',但它依賴於C代碼。 – digEmAll

+0

@digEmAll:即使您在C中操作它們,data.frames也很慢,但我從來沒有看過data.table源代碼。 –

回答

101

看起來像Wes可能在data.table中發現了一個已知問題,此時唯一字符串的數量(級別)很大:10,000。

是否Rprof()顯示通話中花費的大部分時間sortedmatch(levels(i[[lc]]), levels(x[[rc]])?這不是真正的連接本身(算法),而是一個初步步驟。

最近的努力已經進入允許密鑰中的字符列,這應該通過更密切地與R自己的全局字符串哈希表進行集成來解決該問題。一些基準測試結果已經由test.data.table()報告,但該代碼還沒有連接起來,以將級別替換爲級別匹配。

對於常規整數列,大熊貓的合併速度是否快於data.table?這應該是隔離算法本身與因素問題的一種方式。

另外,data.table時間系列合併記。兩個方面:i)多列訂購鍵如(id,datetime)ii)快速流行加入(roll=TRUE)又名a.a.最後一次觀察結轉。

我需要一些時間來確認,因爲這是我看到的第一個與data.table的比較。從data.table v1.8.0


UPDATE釋放除去和匹配I水平至x水平類型的列時與chmatch() 取代2012年7月

  • 內部功能sortedmatch() '因子'。這個 的預備步驟在因子列的水平數量很大(例如> 10,000)時導致(已知的)顯着減速。 加入四個這樣的列的測試加劇,如Wes McKinney (Python包Pandas的作者)所示。例如,匹配100萬個字符串,其中 ,其中600,000個是獨特的,現在從16秒減少到0.5秒。

還在於釋放是:現在

  • 字符列中的鍵,允許和是優選的,以 因素。 data.table()和setkey()不再強制字符爲 因子。因素仍然受支持。實施FR#1493,FR#1224 和(部分)FR#951。

  • 新函數chmatch()和%chin%,匹配的更快版本() 和字符向量的百分比%。 R的內部字符串緩存是 (不建立哈希表)。它們比匹配()在匹配()上的匹配速度快4倍左右。

截止到2013年9月,data.table在CRAN上是v1.8.10,我們正在研究v1.9.0。 NEWS現場更新。


但正如我最初寫的,上面:

data.table時間序列考慮合併。兩個方面即:i) 多列訂購密鑰如(id,datetime)ii)快速流行 加入(roll=TRUE)又名a.a.最後的觀察結轉。

因此,兩個字符列的Pandas equi連接可能仍然比data.table更快。因爲它聽起來像是將兩列合併在一起。 data.table不會散列密鑰,因爲它具有流行的有序連接。 data.table中的「key」實際上就是排序順序(類似於SQL中的聚簇索引;即數據在RAM中的排序方式)。例如,列表中添加了輔助鍵。

總而言之,由於已知問題已得到解決,現在使用超過10,000個獨特字符串的特定雙字符列測試強調的顯着速度差異現在應該不會那麼糟糕。

+4

如果您提供了一個相當大的實際數據集的測試用例,我很樂意運行基準測試。你也歡迎你。實際上,我還沒有優化整數連接鍵大小寫的代碼(把它放在我的待辦事項列表中!),但是您可以預期在連接的演示文稿中給出的散列表研究的字符串大小比性能要好得多。 –

+17

我不使用這些庫中的任何一個,但很高興看到來自R方的Matthew Dowle形式的建設性迴應。 – SlowLearner

+2

以下是一些Rprof結果http://pastie.org/3258362。它看起來有20-40%的時間花在sortmatch上,具體取決於連接類型。另一次需要查看整數列 - 我提出了一個熊貓GitHub問題,提醒我優化該案例(https://github.com/wesm/pandas/issues/682) –

186

大熊貓更快的原因是因爲我想出了一個更好的算法,使用a fast hash table implementation - klib和C/Cython非常仔細地實現,以避免Python解釋器對非矢量化部分的開銷。該算法在我的演示文稿中有詳細描述:A look inside pandas design and development

data.table的比較其實是有點有趣,因爲的r data.table的全部意義在於,它包含預先計算的指標各種列加速諸如數據選擇和合並操作。在這種情況下(數據庫連接)熊貓的DataFrame包含沒有預先計算的信息正在用於合併,可以說這是一個「冷」合併。如果我存儲了連接鍵的因式分解版本,則連接速度將顯着加快 - 因爲分解是此算法的最大瓶頸。

我還應該補充說,pandas的DataFrame的內部設計比R的data.frame(這只是內部數組的一個列表)更適合於這些類型的操作。

+71

當然,現在你已經在python中找到了它,它應該很容易翻譯成R;) – hadley

+36

但是爲什麼有人想要? :) – ely

+9

嗯......也許是因爲他們希望數據操作在R中更快?只是猜測:)) – lebatsnok

28

該主題已有兩年曆史,但似乎是人們搜索熊貓和數據進行比較時可能出現的地方。表

由於這兩種演變隨着時間的推移,我要發佈(2014年),一個相對較新的比較這裏感興趣的用戶:https://github.com/Rdatatable/data.table/wiki/Benchmarks-:-Grouping

這將是有趣的知道,如果韋斯和/或馬特(順便說一下,他們分別是Pandas和data.table的創建者,並且都有上面的評論)還有任何新消息要添加在這裏。

- 更新 -

通過jangorecki貼在下面的註釋包含一個鏈接,我認爲是非常有用的:https://github.com/szilard/benchm-databases

https://github.com/szilard/benchm-databases/blob/master/plot.png

此圖描繪了聚集的平均時間和連接操作對於不同的技術(更低=更快;比較最後更新於2016年9月)。這對我來說真的很有教育意義。

回過頭來看看這個問題,R DT keyR DT指的r data.table的鍵/無鎖的口味和恰巧在這個基準比Python的熊貓(Py pandas)更快。

+1

我正要發佈這個!感謝您的加入。 – Zach

+0

我希望有人能儘快加入聯盟基準! – Zach

+6

@Zach看到這個:https://github.com/szilard/benchm-databases,這也不錯:https://speakerdeck.com/szilard/r-stories-from-the-trenches-budapest-r-meetup -aug-2015 – jangorecki