2012-01-24 18 views
141

Hace poco encontré la biblioteca pandas para python, que de acuerdo con this benchmark realiza fusiones en memoria muy rápidas. Es incluso más rápido que el paquete data.table en R (mi lenguaje de elección para el análisis).¿Por qué los pandas se fusionan en Python más rápido que data.table combina en R?

¿Por qué es pandas mucho más rápido que data.table? ¿Es por una ventaja de velocidad inherente que python tiene sobre R, o hay alguna compensación de la que no tengo conocimiento? ¿Hay alguna manera de realizar uniones internas y externas en data.table sin recurrir a merge(X, Y, all=FALSE) y merge(X, Y, all=TRUE)?

Comparison

Aquí está la R code y la Python code utilizado para referencia de los diversos paquetes.

+0

Mi hipótesis: porque data.table se basa en data.frame y data.frames son lentos. Y creo que la mayoría del código de combinación de pandas está en Cython. –

+10

@JoshuaUlrich: IIRC 'data.table' simplemente hereda de' data.frame', pero depende del código C bajo el capó. – digEmAll

+0

@digEmAll: data.frames son lentos incluso si los manipulas en C, pero nunca he visto la fuente data.table. –

Respuesta

101

Parece que Wes puede haber descubierto un problema conocido en data.table cuando el número de cadenas únicas (niveles ) es grande: 10.000.

¿Revela Rprof() la mayor parte del tiempo pasado en la llamada sortedmatch(levels(i[[lc]]), levels(x[[rc]])? Esto no es realmente la unión en sí misma (el algoritmo), sino un paso preliminar.

Se han realizado esfuerzos recientes para permitir columnas de caracteres en las claves, lo que debería resolver ese problema al integrarse más estrechamente con la tabla de hash de cadena global propia de R. Algunos resultados de referencia ya han sido informados por test.data.table(), pero ese código aún no está conectado para reemplazar los niveles por la coincidencia de niveles.

¿Los pandas se funden más rápido que data.table para las columnas enteras normales? Esa debería ser una forma de aislar el algoritmo en sí mismo frente a los problemas de los factores.

Además, data.table tiene series de tiempo merge en mente. Dos aspectos de eso: i) multi columna pedidos claves como (id, datetime) ii) unión prevaleciente rápida (roll=TRUE) a.k.a última observación transferida.

Voy a necesitar algo de tiempo para confirmar, ya que es el primero que he visto de la comparación de data.table como se presenta.


actualización desde v1.8.0 data.table publicada en julio de 2,012

  • función interna sortedmatch() eliminado y reemplazado con chmatch() cuando a juego i niveles a los niveles de x para las columnas de tipo 'factor'. Este paso preliminar estaba causando una desaceleración (conocida) significativa cuando el número de los niveles de una columna de factores era grande (por ejemplo,> 10,000). Exacerbado en pruebas de unir cuatro de tales columnas, como lo demostró Wes McKinney (autor del paquete de Python Pandas). Con un millón de cadenas de las cuales , de las cuales 600,000 son únicas, ahora se reduce de 16s a 0.5s, por ejemplo.

también en que la liberación fue:

  • columnas de caracteres ahora están permitidos en las llaves y se prefieren a factor. data.table() y setkey() ya no fuerzan el carácter al factor . Los factores aún son compatibles. Implementa FR # 1493, FR # 1224 y (parcialmente) FR # 951.

  • Nuevas funciones chmatch() y% chin%, versiones más rápidas de match() y% en% para vectores de caracteres. El caché de cadenas interno de R es utilizado (no se construye una tabla hash). Son aproximadamente 4 veces más rápidos que que coinciden() en el ejemplo de? Chmatch.

A partir de septiembre de 2013 data.table es v1.8.10 en CRAN y estamos trabajando en v1.9.0. NEWS se actualiza en vivo.


Pero como he escrito originalmente, arriba:

data.table tiene series de tiempo se funden en mente. Dos aspectos para eso: i) multi columna pedidos claves como (id, datetime) ii) prevalecen rápidamente join (roll=TRUE) a.k.a última observación transferida.

Así que el equi pandas se unen de dos columnas de caracteres es probablemente aún más rápido que data.table. Ya que suena como hash las dos columnas combinadas. data.table no copia la clave porque tiene en cuenta las combinaciones ordenadas predominantes. Una "clave" en data.table es literalmente solo el orden de clasificación (similar a un índice agrupado en SQL; es decir, así es como se ordenan los datos en la RAM). En la lista está agregar claves secundarias, por ejemplo.

En resumen, la marcada diferencia de velocidad resaltada por esta prueba de columna de dos caracteres en particular con más de 10,000 cadenas únicas no debería ser tan mala ahora, ya que el problema conocido se ha solucionado.

+4

Si proporciona un caso de prueba para un conjunto de datos razonablemente grande, realista, estaré feliz de ejecutar los puntos de referencia. Eres más que bienvenido, también. De hecho, todavía no he optimizado el código para el caso de la clave de unión de enteros (¡póngalo en mi lista de tareas pendientes!), Pero puede esperar un rendimiento significativamente mejor que el caso de cadenas dado el estudio de tablas hash en la presentación vinculada. –

+17

No uso ninguna de estas bibliotecas pero me complace ver una respuesta constructiva del lado R en la forma de Matthew Dowle. – SlowLearner

+2

Aquí hay algunos resultados de Rprof http://pastie.org/3258362. Parece que el 20-40% del tiempo se gasta en una coincidencia ordenada según el tipo de combinación. Tendré que buscar columnas enteras en otro momento. Hice un problema de pandas GitHub para recordarme que optimice ese caso (https://github.com/wesm/pandas/issues/682) –

186

La razón por la que los pandas es más rápido es porque se me ocurrió con un mejor algoritmo, que se realiza con mucho cuidado usando a fast hash table implementation - klib y en C/Cython para evitar la sobrecarga intérprete de Python para las partes no vectorizable. El algoritmo se describe con cierto detalle en mi presentación: A look inside pandas design and development.

La comparación con data.table es en realidad un poco interesante porque todo el punto de R data.table es que contiene índices precalculados por varias columnas para acelerar las operaciones como la selección de datos y fusiones. En este caso (las uniones de base de datos) pandas 'DataFrame contiene no se ha calculado previamente la información que se está utilizando para la fusión, por así decirlo, es una fusión "fría". Si hubiera almacenado las versiones factorizadas de las claves de combinación, la unión sería significativamente más rápida, ya que la factorización es el mayor cuello de botella para este algoritmo.

Debo añadir que el diseño interno del DataFrame de los pandas es mucho más adecuado para este tipo de operaciones que el data.frame de R (que es solo una lista de arreglos internos).

+71

Por supuesto, ahora que ya lo has descifrado en python, debería ser fácil traducirlo a R;) – hadley

+36

¿Pero por qué alguien querría hacerlo? :) – ely

+9

Umm ... tal vez porque querrían que las operaciones de datos fueran más rápidas en R? Solo adivinando :)) – lebatsnok

28

Este tema tiene dos años pero parece un lugar probable para que las personas aterricen cuando buscan comparaciones de pandas y datos.tabla

Dado que ambos han evolucionado con el tiempo, quiero publicar una comparación relativamente reciente (de 2014) aquí por los usuarios interesados: https://github.com/Rdatatable/data.table/wiki/Benchmarks-:-Grouping

Sería interesante saber si Wes y/o mate (quienes, dicho sea de paso, son creadores de Pandas y data.table respectivamente y han comentado ambos arriba) tienen alguna noticia para agregar aquí también.

- ACTUALIZACIÓN -

Un comentario publicado por debajo jangorecki contiene un enlace que creo que es muy útil: https://github.com/szilard/benchm-databases

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

Este gráfico muestra los tiempos medios de agregación y se unen a las operaciones para diferentes tecnologías (inferior = más rápido; última actualización de la comparación en septiembre de 2016). Fue realmente educativo para mí.

Volviendo a la pregunta, y R DT keyR DT se refieren a los sabores con llave/no manipulada de R data.table y pasar a ser más rápido en este punto de referencia distinto de las pandas de Python (Py pandas).

+1

¡Estaba a punto de publicar esto! Gracias por añadir. – Zach

+0

¡Espero que alguien también se una a un punto de referencia pronto! – Zach

+6

@Zach ver esto: https://github.com/szilard/benchm-databases y que también es muy bueno: https://speakerdeck.com/szilard/r-stories-from-the-trenches-budapest-r-meetup -aug-2015 – jangorecki

Cuestiones relacionadas