Recientemente me encontré con la biblioteca de pandas para Python, que según este punto de referencia 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é es pandas
mucho más rápido que data.table
? ¿Se debe a una ventaja de velocidad inherente que tiene Python sobre R, o hay alguna compensación que no conozco? ¿Hay alguna manera de realizar uniones internas y externas data.table
sin recurrir a merge(X, Y, all=FALSE)
y merge(X, Y, all=TRUE)
?
Aquí está el código R y el código Python utilizado para comparar los diversos paquetes.
data.table
simplemente hereda dedata.frame
, pero se basa en el código C bajo el capó.set()
se agregódata.table
poco después de esta discusión. Muy similar:=
pero evita la pequeña sobrecarga de[.data.table
cuando se coloca en bucle y, en consecuencia, es tan rápido comomatrix
. Por lo tanto,data.frame
se puede manipular tan rápido como la matriz. El punto de referencia está aquí .Respuestas:
Parece que Wes pudo haber descubierto un problema conocido
data.table
cuando la cantidad de cadenas únicas ( niveles ) es grande: 10,000.¿
Rprof()
Revela la mayor parte del tiempo dedicado a la llamadasortedmatch(levels(i[[lc]]), levels(x[[rc]])
? Esto no es realmente la unión en sí (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 propia tabla global de hash de cadenas de R. Ya se informan algunos resultados de referencia,
test.data.table()
pero ese código aún no está conectado para reemplazar los niveles de coincidencia de niveles.¿Los pandas se fusionan más rápido que
data.table
las columnas enteras normales? Esa debería ser una forma de aislar el algoritmo en sí mismo frente a los factores.Además,
data.table
tiene series temporales fusionadas en mente. Dos aspectos a eso: i) claves ordenadas de múltiples columnas como (id, fecha y hora) ii) unión prevaleciente rápida (roll=TRUE
) también conocida como última observación llevada adelante.Necesitaré algo de tiempo para confirmar, ya que es la primera vez que veo la comparación con la
data.table
presentada.ACTUALIZACIÓN de data.table v1.8.0 lanzado en julio de 2012
También en ese lanzamiento fue:
las columnas de caracteres ahora están permitidas en las claves y se prefieren factorizar. data.table () y setkey () ya no obligan al personaje a factorizar. 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% in% para vectores de caracteres. Se utiliza el caché de cadenas interno de R (no se crea una tabla hash). Son aproximadamente 4 veces más rápidos que match () en el ejemplo en? Chmatch.
A partir de septiembre de 2013 data.table es v1.8.10 en CRAN y estamos trabajando en v1.9.0. NOTICIAS se actualiza en vivo.
Pero como escribí originalmente, arriba:
Por lo tanto, la unión equitativa de dos columnas de caracteres de Pandas probablemente sea aún más rápida que data.table. Ya que suena como hash las dos columnas combinadas. data.table no teclea la clave porque tiene en mente 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 RAM). En la lista hay que agregar claves secundarias, por ejemplo.
En resumen, la deslumbrante diferencia de velocidad resaltada por esta prueba particular de columna de dos caracteres con más de 10,000 cadenas únicas no debería ser tan mala ahora, ya que el problema conocido se ha solucionado.
fuente
La razón por la que pandas es más rápido es porque se me ocurrió un algoritmo mejor, que se implementa con mucho cuidado utilizando una implementación rápida de tabla hash: klib y en C / Cython para evitar la sobrecarga del intérprete de Python para las partes no vectorizables. El algoritmo se describe con cierto detalle en mi presentación: una mirada al diseño y desarrollo de pandas .
La comparación con
data.table
es realmente un poco interesante porque el objetivo de las Rdata.table
es que contiene índices precalculados para varias columnas para acelerar operaciones como la selección de datos y las fusiones. En este caso (la base de datos se une), el DataFrame de pandas no contiene información precalculada que se esté utilizando para la fusión, por así decirlo, es una fusión "en frío". Si hubiera almacenado las versiones factorizadas de las teclas de combinación, la combinación sería significativamente más rápida, ya que la factorización es el mayor cuello de botella para este algoritmo.También debo agregar que el diseño interno del DataFrame de 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).
fuente
data.table
fueron impulsados principalmente por un error que desde entonces se ha solucionado. ¿Hay alguna posibilidad de que pueda volver a ejecutar su punto de referencia y escribir una publicación de blog actualizada?Este tema tiene dos años pero parece un lugar probable para que la gente aterrice cuando buscan comparaciones de pandas y datos.
Dado que ambos han evolucionado con el tiempo, quiero publicar una comparación relativamente nueva (desde 2014) aquí para los usuarios interesados: https://github.com/Rdatatable/data.table/wiki/Benchmarks-:-Grouping
Sería interesante saber si Wes y / o Matt (que, por cierto, son creadores de Pandas y data.table respectivamente y ambos han comentado anteriormente) tienen alguna noticia que agregar aquí también.
- ACTUALIZACIÓN -
Un comentario publicado a continuación por jangorecki contiene un enlace que creo que es muy útil: https://github.com/szilard/benchm-databases
Este gráfico muestra los tiempos promedio de agregación y operaciones de unión para diferentes tecnologías ( menor = más rápido ; comparación actualizada por última vez en septiembre de 2016). Fue realmente educativo para mí.
Volviendo a la pregunta,
R DT key
yR DT
se refieren a los sabores con clave / sin codificar 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
).fuente
Hay excelentes respuestas, especialmente hechas por los autores de ambas herramientas sobre las que se formula la pregunta. La respuesta de Matt explica el caso reportado en la pregunta, que fue causado por un error y no por un algoritmo de fusión. El error se solucionó al día siguiente, hace más de 7 años.
En mi respuesta, proporcionaré algunos tiempos actualizados de operación de fusión para data.table y pandas. Tenga en cuenta que plyr y base R merge no están incluidos.
Los tiempos que presento provienen del proyecto db-benchmark , un punto de referencia reproducible que se ejecuta continuamente. Actualiza las herramientas a versiones recientes y vuelve a ejecutar scripts de referencia. Ejecuta muchas otras soluciones de software. Si está interesado en Spark, Dask y algunos otros, asegúrese de consultar el enlace.
A partir de ahora ... (aún por implementar: un tamaño de datos más y 5 preguntas más)
Probamos 2 tamaños de datos diferentes de la tabla LHS.
Para cada uno de esos tamaños de datos, ejecutamos 5 preguntas de fusión diferentes.
La mesa RHS es de 3 tamaños diferentes.
En todos los casos, hay alrededor del 90% de las filas coincidentes entre LHS y RHS, y no hay duplicados en la columna de unión de RHS (sin producto cartesiano).
A partir de ahora (se ejecuta el 2 de noviembre de 2019)
pandas 0.25.3 lanzado el 1 de noviembre de 2019
data.table 0.12.7 (92abb70) lanzado el 2 de noviembre de 2019
Los tiempos siguientes son en segundos, para dos tamaños de datos diferentes de LHS. La columna
pd2dt
se agrega a la relación de almacenamiento de campo de cuántas veces los pandas son más lentos que data.table.fuente