Je suis récemment tombé sur la bibliothèque pandas pour python, qui selon cette référence effectue des fusions en mémoire très rapides. C'est encore plus rapide que le package data.table en R (ma langue de choix pour l'analyse).
Pourquoi pandas
est-il tellement plus rapide que data.table
? Est-ce à cause d'un avantage inhérent à la vitesse python a sur R, ou y a-t-il un compromis que je ne connais pas? Existe-t-il un moyen d'effectuer des jointures internes et externes dans data.table
sans recourir à merge(X, Y, all=FALSE)
et merge(X, Y, all=TRUE)
?
Voici le code R et le code Python utilisés pour comparer les différents packages.
Il semble que Wes ait pu découvrir un problème connu dans data.table
Lorsque le nombre de chaînes uniques ( niveaux) est important: 10 000.
Rprof()
révèle-t-il la plupart du temps passé dans l'appel sortedmatch(levels(i[[lc]]), levels(x[[rc]])
? Ce n'est pas vraiment la jointure elle-même (l'algorithme), mais une étape préliminaire.
Des efforts récents ont été consentis pour autoriser les colonnes de caractères dans les clés, ce qui devrait résoudre ce problème en s'intégrant plus étroitement à la propre table de hachage de chaîne globale de R. Certains résultats de référence sont déjà signalés par test.data.table()
mais ce code n'est pas encore connecté pour remplacer les niveaux à niveaux correspondent.
Est-ce que pandas fusionne plus rapidement que data.table
Pour les colonnes entières régulières? Cela devrait être un moyen d'isoler l'algorithme lui-même par rapport aux problèmes de facteur.
De plus, data.table
A fusion de séries chronologiques en tête. Deux aspects à cela: i) plusieurs colonnes ordonné clés telles que (id, datetime) ii) jointure dominante rapide (roll=TRUE
) A.k.a. dernière observation reportée.
Il me faudra un peu de temps pour confirmer car c'est la première fois que je vois la comparaison avec data.table
Tel que présenté.
MISE À JOUR de data.table v1.8.0 publiée en juillet 2012
également dans cette version:
les colonnes de caractères sont désormais autorisées dans les clés et sont préférées à factoriser. data.table () et setkey () ne contraignent plus le caractère à factoriser. Les facteurs sont toujours pris en charge. Met en œuvre FR # 1493, FR # 1224 et (partiellement) FR # 951.
Nouvelles fonctions chmatch () et% chin%, versions plus rapides de match () et% en% pour les vecteurs de caractères. Le cache de chaîne interne de R est utilisé (aucune table de hachage n'est construite). Ils sont environ 4 fois plus rapides que match () dans l'exemple de? Chmatch.
Depuis septembre 2013, data.table est v1.8.10 sur CRAN et nous travaillons sur v1.9.0. ACTUALITÉS est mis à jour en direct.
Mais comme je l'ai écrit à l'origine, ci-dessus:
data.table
A fusion de séries chronologiques en tête. Deux aspects à cela: i) plusieurs colonnes ordonné clés telles que (id, datetime) ii) jointure dominante rapide (roll=TRUE
) A.k.a. dernière observation reportée.
Ainsi, la liaison Pandas equi de deux colonnes de caractères est probablement encore plus rapide que data.table. Comme il semble qu'elle hache les deux colonnes combinées. Data.table ne hache pas la clé car elle a les ordonnances dominantes à l'esprit. Une "clé" dans data.table est littéralement juste l'ordre de tri (semblable à un index clusterisé dans SQL; c'est-à-dire, c'est comme ça que les données sont ordonnées dans la RAM). Sur la liste est d'ajouter des clés secondaires, par exemple.
En résumé, la différence de vitesse flagrante mise en évidence par ce test de colonne à deux caractères particulier avec plus de 10 000 chaînes uniques ne devrait pas être aussi mauvaise maintenant, car le problème connu a été corrigé.
La raison pandas est plus rapide parce que j'ai trouvé un meilleur algorithme, qui est implémenté très soigneusement en utilisant ne implémentation rapide de table de hachage - klib et en C/- Cython pour éviter la surcharge de l'interpréteur Python pour les parties non vectorisables. L'algorithme est décrit en détail dans ma présentation: Un regard à l'intérieur pandas conception et développement .
La comparaison avec data.table
est en fait un peu intéressant parce que tout l'intérêt de R data.table
est qu'il contient des index précalculés pour diverses colonnes afin d'accélérer des opérations telles que la sélection et la fusion de données. Dans ce cas (jointure à la base de données), DataFrame de pandas ne contient aucune information précalculée qui est utilisée pour la fusion, pour ainsi dire c'est un "froid" fusionner. Si j'avais stocké les versions factorisées des clés de jointure, la jointure serait beaucoup plus rapide - car la factorisation est le plus gros goulot d'étranglement pour cet algorithme.
Je dois également ajouter que la conception interne du DataFrame de pandas se prête beaucoup mieux à ce type d'opérations que le data.frame de R (qui n'est qu'une liste de tableaux en interne).
Ce sujet a deux ans mais semble être un endroit probable pour que les gens atterrissent lorsqu'ils recherchent des comparaisons de Pandas et data.table
Étant donné que ces deux éléments ont évolué au fil du temps, je souhaite publier ici une comparaison relativement récente (à partir de 2014) pour les utilisateurs intéressés: https://github.com/Rdatatable/data.table/wiki/Benchmarks-: -Grouping
Il serait intéressant de savoir si Wes et/ou Matt (qui, soit dit en passant, sont des créateurs de Pandas et data.table respectivement et ont tous deux commenté ci-dessus) ont des nouvelles à ajouter ici comme bien.
-- MISE À JOUR --
Un commentaire posté ci-dessous par jangorecki contient un lien qui je pense est très utile: https://github.com/szilard/benchm-databases
Ce graphique illustre la durée moyenne des opérations d'agrégation et de jointure pour différentes technologies ( inférieure = plus rapide ; comparaison mise à jour pour la dernière fois en septembre 2016). C'était vraiment instructif pour moi.
Pour en revenir à la question, R DT key
et R DT
fait référence aux saveurs à clé/sans clé de data.table de R et se trouve être plus rapide dans cette référence que Python Pandas (Py pandas
).