{"id":570125,"date":"2024-07-04T14:58:03","date_gmt":"2024-07-04T13:58:03","guid":{"rendered":"https:\/\/blog.jetbrains.com\/pycharm\/2024\/07\/polars-vs-pandas\/"},"modified":"2025-05-23T20:59:27","modified_gmt":"2025-05-23T19:59:27","slug":"polars-vs-pandas","status":"publish","type":"pycharm","link":"https:\/\/blog.jetbrains.com\/es\/pycharm\/2024\/07\/polars-vs-pandas\/","title":{"rendered":"Polars vs. pandas: \u00bfen qu\u00e9 se diferencian?"},"content":{"rendered":"<p>Si est\u00e1 al tanto de los avances en los marcos de datos de Python del \u00faltimo a\u00f1o, seguramente haya o\u00eddo hablar de <a href=\"https:\/\/www.pola.rs\/\" target=\"_blank\" rel=\"noopener\">Polars<\/a>, la potente biblioteca de marcos de datos dise\u00f1ada para trabajar con grandes conjuntos de datos.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-384206\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/08\/Preview-page-1280x720-2x-1.jpg\" alt=\"\" width=\"2560\" height=\"1440\" \/><\/figure>\n<p align=\"center\"><a class=\"jb-download-button\" href=\"https:\/\/www.jetbrains.com\/dataspell\/\" target=\"_blank\" rel=\"noopener\"><br \/>Probar Polars en DataSpell<br \/><\/a><\/p>\n<p>A diferencia de otras bibliotecas para trabajar con grandes conjuntos de datos, como <a href=\"https:\/\/spark.apache.org\/\" target=\"_blank\" rel=\"noopener\">Spark<\/a>, <a href=\"https:\/\/www.dask.org\/\" target=\"_blank\" rel=\"noopener\">Dask<\/a> y <a href=\"https:\/\/www.ray.io\/\" target=\"_blank\" rel=\"noopener\">Ray<\/a>, Polars est\u00e1 dise\u00f1ada para ser utilizada en una sola m\u00e1quina, lo que provoca muchas comparaciones con <a href=\"https:\/\/pandas.pydata.org\/\" target=\"_blank\" rel=\"noopener\">pandas<\/a>. Sin embargo, Polars difiere de pandas en varios aspectos importantes, como la forma en que trabaja con los datos y cu\u00e1les son sus aplicaciones \u00f3ptimas. En el siguiente art\u00edculo, exploraremos los detalles t\u00e9cnicos que diferencian a estas dos bibliotecas de marcos de datos y echaremos un vistazo a los puntos fuertes y las limitaciones de cada una.<\/p>\n<p>Si desea saber m\u00e1s sobre este tema de boca del creador de Polars, <a href=\"https:\/\/github.com\/ritchie46\" target=\"_blank\" rel=\"noopener\">Ritchie Vink<\/a>, puede ver tambi\u00e9n nuestra entrevista con \u00e9l a continuaci\u00f3n.<\/p>\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\">\n<div class=\"wp-block-embed__wrapper\"><iframe loading=\"lazy\" title=\"\u00bfQu\u00e9 es Polars?\" src=\"https:\/\/www.youtube.com\/embed\/QfLzEp-yt_U?feature=oembed\" width=\"500\" height=\"281\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/div>\n<\/figure>\n<h2 class=\"wp-block-heading\">\u00bfPor qu\u00e9 utilizar Polars en lugar de pandas?<\/h2>\n<p>En una palabra: rendimiento. Polars se cre\u00f3 desde cero para ser rapid\u00edsimo y puede realizar operaciones comunes unas 5-10 veces m\u00e1s r\u00e1pido que pandas. Adem\u00e1s, las operaciones de Polars requieren significativamente menos memoria que las de pandas: pandas requiere alrededor de 5 a 10 veces m\u00e1s RAM que el tama\u00f1o del conjunto de datos para realizar las operaciones, frente a las 2 a 4 veces necesarias para Polars.<\/p>\n<p>Puede hacerse una idea de c\u00f3mo funciona Polars en comparaci\u00f3n con otras bibliotecas de marcos de datos <a href=\"https:\/\/duckdblabs.github.io\/db-benchmark\/\" target=\"_blank\" rel=\"noopener\">aqu\u00ed<\/a>. Como ve, Polars es entre 10 y 100 veces m\u00e1s r\u00e1pida que pandas para las operaciones comunes y, de hecho, es una de las bibliotecas DataFrame m\u00e1s r\u00e1pidas en general. Adem\u00e1s, puede manejar conjuntos de datos m\u00e1s grandes que pandas antes de sufrir errores de falta de memoria.<\/p>\n<h2 class=\"wp-block-heading\">\u00bfPor qu\u00e9 Polars es tan r\u00e1pido?<\/h2>\n<p>Estos resultados son muy impresionantes, por lo que se estar\u00e1 preguntando: \u00bfc\u00f3mo puede Polars obtener este tipo de rendimiento ejecut\u00e1ndose solo en una m\u00e1quina? La biblioteca se dise\u00f1\u00f3 teniendo en cuenta el rendimiento desde el principio, y esto se consigue gracias a varios factores.<\/p>\n<h3 class=\"wp-block-heading\">Escrita en Rust<\/h3>\n<p>Uno de los datos m\u00e1s conocidos de Polars es que est\u00e1 escrito en <a href=\"https:\/\/www.rust-lang.org\/\" target=\"_blank\" rel=\"noopener\">Rust<\/a>, un lenguaje de bajo nivel que es casi tan r\u00e1pido como C y C++. En cambio, pandas se basa en bibliotecas de Python, una de las cuales es <a href=\"https:\/\/numpy.org\/\" target=\"_blank\" rel=\"noopener\">NumPy<\/a>. Aunque el n\u00facleo de NumPy est\u00e1 escrito en C, sigue lastrado por problemas inherentes a la forma en que Python maneja ciertos tipos en memoria, como las cadenas para datos categ\u00f3ricos, lo que provoca un rendimiento deficiente al manejar estos tipos (para conocer m\u00e1s detalles, consulte <a href=\"https:\/\/wesmckinney.com\/blog\/apache-arrow-pandas-internals\/\" target=\"_blank\" rel=\"noopener\">este fant\u00e1stico art\u00edculo del blog<\/a> de <a href=\"https:\/\/wesmckinney.com\/\" target=\"_blank\" rel=\"noopener\">Wes McKinney<\/a>).<\/p>\n<p>Otra de las ventajas de utilizar Rust es que permite una concurrencia segura; es decir, est\u00e1 dise\u00f1ado para que el paralelismo sea lo m\u00e1s predecible posible. Esto significa que Polars puede utilizar con seguridad todos los n\u00facleos de su m\u00e1quina incluso para consultas complejas que impliquen varias columnas, lo que llev\u00f3 a Ritchie Vink a describir el rendimiento de Polar como \u00abvergonzosamente paralelo\u00bb. Esto proporciona a Polars un enorme aumento del rendimiento con respecto a pandas, que solo utiliza un n\u00facleo para realizar las operaciones. Eche un vistazo a <a href=\"https:\/\/www.youtube.com\/watch?v=7xcUvzERwx0&amp;ab_channel=PyData\" target=\"_blank\" rel=\"noopener\">esta excelente charla<\/a> de Nico Kreiling de la PyCon DE de este a\u00f1o, que entra en m\u00e1s detalle sobre c\u00f3mo consigue esto Polars.<\/p>\n<h3 class=\"wp-block-heading\">Basada en Arrow<\/h3>\n<p>Otro factor que contribuye al impresionante rendimiento de Polars es <a href=\"https:\/\/arrow.apache.org\/\" target=\"_blank\" rel=\"noopener\">Apache Arrow<\/a>, un formato de memoria independiente del lenguaje. Arrow fue en realidad cocreado por Wes McKinney en respuesta a muchos de los problemas que detect\u00f3 en pandas a medida que el tama\u00f1o de los datos se disparaba. Tambi\u00e9n es el backend de pandas 2.0, una versi\u00f3n de pandas con m\u00e1s rendimiento lanzada en 2023. Sin embargo, los backends de Arrow de las bibliotecas difieren ligeramente: mientras que pandas 2.0 se ha creado sobre PyArrow, el equipo de Polars cre\u00f3 su propia implementaci\u00f3n de Arrow.<\/p>\n<p>Una de las principales ventajas de crear una biblioteca de datos en Arrow es la interoperabilidad. Arrow se ha dise\u00f1ado para estandarizar el formato de datos en memoria utilizado en todas las bibliotecas, y ya lo utilizan varias bibliotecas y bases de datos importantes, como puede ver <a href=\"https:\/\/arrow.apache.org\/overview\/\" target=\"_blank\" rel=\"noopener\">a continuaci\u00f3n<\/a>.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-375452\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/07\/arrow.png\" alt=\"\" width=\"574\" height=\"318\" \/><\/figure>\n<\/div>\n<p><a href=\"https:\/\/datapythonista.me\/blog\/pandas-20-and-the-arrow-revolution-part-i\" target=\"_blank\" rel=\"noopener\">Esta interoperabilidad<\/a> acelera el rendimiento, ya que evita la necesidad de convertir los datos a un formato diferente para pasarlos entre los distintos pasos del proceso de datos (en otras palabras, evita la necesidad de serializar y deserializar los datos). Tambi\u00e9n es m\u00e1s eficiente desde el punto de vista de la memoria, ya que dos procesos pueden compartir los mismos datos sin necesidad de hacer una copia. Dado que se estima que la serializaci\u00f3n\/deserializaci\u00f3n <a href=\"https:\/\/arrow.apache.org\/faq\/\" target=\"_blank\" rel=\"noopener\">representa el 80-90 % de los costes de computaci\u00f3n<\/a> en los flujos de trabajo de datos, el formato com\u00fan de datos de Arrow proporciona a Polars importantes ganancias de rendimiento.<\/p>\n<p>Arrow tambi\u00e9n integra compatibilidad con una gama m\u00e1s amplia de tipos de datos que pandas. Como pandas est\u00e1 basado en NumPy, es excelente en el manejo de columnas de enteros y flotantes, pero tiene dificultades con otros tipos de datos. <a href=\"https:\/\/datapythonista.me\/blog\/pandas-20-and-the-arrow-revolution-part-i\" target=\"_blank\" rel=\"noopener\">Por el contrario<\/a>, Arrow cuenta con una sofisticada compatibilidad con tipos de columnas datetime, boolean, binary e incluso complejas, como las que contienen listas. Adem\u00e1s, Arrow es capaz de manejar de forma nativa los datos que faltan, lo que requiere una soluci\u00f3n en NumPy.<\/p>\n<p>Por \u00faltimo, Arrow utiliza el almacenamiento de datos en columnas, lo que significa que, independientemente del tipo de datos, todas las columnas se almacenan en un bloque continuo de memoria. Esto no solo facilita el paralelismo, sino que tambi\u00e9n agiliza la recuperaci\u00f3n de datos.<\/p>\n<h3 class=\"wp-block-heading\">Optimizaci\u00f3n de consultas<\/h3>\n<p>Otro de los n\u00facleos del rendimiento de Polars es c\u00f3mo eval\u00faa el c\u00f3digo. Pandas, por defecto, utiliza la <em>ejecuci\u00f3n inmediata<\/em>, que consiste en ejecutar las operaciones en el orden en que usted las ha escrito. Por el contrario, Polars tiene la capacidad de realizar tanto una ejecuci\u00f3n inmediata como una <em>ejecuci\u00f3n pospuesta<\/em>, en la que un optimizador de consultas evaluar\u00e1 todas las operaciones necesarias y trazar\u00e1 la forma m\u00e1s eficiente de ejecutar el c\u00f3digo. Esto puede incluir, entre otras cosas, reescribir el orden de ejecuci\u00f3n de las operaciones o eliminar c\u00e1lculos redundantes. Tomemos, por ejemplo, la siguiente expresi\u00f3n para obtener la media de la columna <code>Number1<\/code> para cada una de las categor\u00edas \u00abA\u00bb y \u00abB\u00bb en <code>Category<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">(\ndf\n.groupby(by = \"Category\").agg(pl.col(\"Number1\").mean())\n.filter(pl.col(\"Category\").is_in([\"A\", \"B\"]))\n)<\/pre>\n<p>Si esta expresi\u00f3n se ejecuta inmediatamente, la operaci\u00f3n <code>groupby<\/code> se realizar\u00e1 innecesariamente para todo el DataFrame, y despu\u00e9s se filtrar\u00e1 por <code>Category<\/code>. Con la ejecuci\u00f3n pospuesta, se puede filtrar el DataFrame y realizar <code>groupby<\/code> solo con los datos necesarios.<\/p>\n<h3 class=\"wp-block-heading\">API expresiva<\/h3>\n<p>Por \u00faltimo, Polars tiene una API extremadamente expresiva, lo que significa que b\u00e1sicamente cualquier operaci\u00f3n que desee realizar puede expresarse como un m\u00e9todo Polars. En cambio, las operaciones m\u00e1s complejas en pandas a menudo deben pasarse al m\u00e9todo <code>apply<\/code> como una expresi\u00f3n lambda. El problema del m\u00e9todo <code>apply<\/code> es que realiza un bucle sobre las filas del DataFrame y ejecuta secuencialmente la operaci\u00f3n en cada una de ellas. La posibilidad de utilizar m\u00e9todos integrados le permite trabajar a nivel de columnas y aprovechar otra forma de paralelismo denominada SIMD.<\/p>\n<h2 class=\"wp-block-heading\">\u00bfCu\u00e1ndo debe quedarse con pandas?<\/h2>\n<p>Todo esto suena tan estupendo que probablemente se est\u00e9 preguntando por qu\u00e9 molestarse en seguir con pandas. \u00a1Pues no tan r\u00e1pido! Aunque Polars es magn\u00edfico para transformar datos de forma extremadamente eficiente, actualmente no es la elecci\u00f3n \u00f3ptima para la exploraci\u00f3n de datos o para su uso como parte de los procesos de aprendizaje autom\u00e1tico. Estas son \u00e1reas en las que pandas sigue brillando.<\/p>\n<p>Una de las razones es que, aunque Polars tiene una gran interoperabilidad con otros paquetes que utilizan Arrow, <em>a\u00fan<\/em> no es compatible con la mayor\u00eda de los paquetes de visualizaci\u00f3n de datos de Python ni con bibliotecas de aprendizaje autom\u00e1tico como <a href=\"https:\/\/scikit-learn.org\/stable\/\" target=\"_blank\" rel=\"noopener\">scikit-learn<\/a> o <a href=\"https:\/\/pytorch.org\/\" target=\"_blank\" rel=\"noopener\">PyTorch<\/a>. La \u00fanica excepci\u00f3n es <a href=\"https:\/\/plotly.com\/\" target=\"_blank\" rel=\"noopener\">Plotly<\/a>, que le permite crear gr\u00e1ficos directamente a partir de DataFrames de Polars.<\/p>\n<p>Una soluci\u00f3n que se est\u00e1 debatiendo es utilizar el <a href=\"https:\/\/data-apis.org\/dataframe-protocol\/latest\/index.html\" target=\"_blank\" rel=\"noopener\">protocolo de intercambio de DataFrames de Python<\/a> en estos paquetes para que sean compatibles con una serie de bibliotecas de DataFrames, lo que significar\u00eda que los flujos de trabajo de ciencia de datos y aprendizaje autom\u00e1tico ya no se ver\u00edan obstaculizados por pandas. Sin embargo, se trata de una idea relativamente nueva y llevar\u00e1 tiempo poner en marcha estos proyectos.<\/p>\n<h2 class=\"wp-block-heading\">Herramientas para Polars y pandas<\/h2>\n<p>Despu\u00e9s de todo esto, \u00a1seguro que est\u00e1 deseando probar Polars! Tanto DataSpell como <a href=\"https:\/\/www.jetbrains.com\/pycharm\/\" target=\"_blank\" rel=\"noopener\" data-type=\"link\" data-id=\"https:\/\/www.jetbrains.com\/pycharm\/download\/?section=mac\">PyCharm Professional<\/a> 2023.2 ofrecen excelentes herramientas para trabajar tanto con pandas como con Polars en notebooks de Jupyter. En particular, los DataFrames de pandas y Polars se muestran con una funcionalidad interactiva, lo que hace que explorar sus datos sea mucho m\u00e1s r\u00e1pido y c\u00f3modo.<\/p>\n<p>Algunas de mis funcionalidades favoritas son la posibilidad de desplazarse por todas las filas y columnas del DataFrame sin truncarlo, obtener agregaciones de valores del DataFrame con un solo clic y exportar el DataFrame en una enorme variedad de formatos (\u00a1incluido Markdown!).<\/p>\n<p>Si a\u00fan no utiliza DataSpell, puede hacer clic en el siguiente enlace y probarlo durante de 30 d\u00edas.<\/p>\n<p align=\"center\"><a class=\"jb-download-button\" href=\"https:\/\/www.jetbrains.com\/dataspell\/\" target=\"_blank\" rel=\"noopener\"><br \/>\u00a1Pru\u00e9belo!<br \/><\/a><\/p>\n<p style=\"text-align: left;\" align=\"center\">A<em>rt\u00edculo original en ingl\u00e9s de:<\/em><\/p>\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/11\/BK7A9876_korr_sRGB_8_1000x1500px_square_resized-200x200.jpg\" width=\"200\" height=\"200\" alt=\"Jodie Burchell\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                            <h4>Jodie Burchell<\/h4>\n                                        <p>Dr. Jodie Burchell is the Developer Advocate in Data Science at JetBrains, and was previously a Lead Data Scientist at Verve Group Europe. She completed a PhD in clinical psychology and a postdoc in biostatistics, before leaving academia for a data science career. She has worked for 7 years as a data scientist in both Australia and Germany, developing a range of products including recommendation systems, analysis platforms, search engine improvements and audience profiling. She has held a broad range of responsibilities in her career, doing everything from data analytics to maintaining machine learning solutions in production. She is a long time content creator in data science, across conference and user group presentations, books, webinars, and posts on both her own and JetBrain&#8217;s blogs.<\/p>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":1086,"featured_media":570128,"comment_status":"closed","ping_status":"closed","template":"","categories":[952],"tags":[566,8152],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/570125"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/types\/pycharm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/comments?post=570125"}],"version-history":[{"count":4,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/570125\/revisions"}],"predecessor-version":[{"id":570141,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/pycharm\/570125\/revisions\/570141"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media\/570128"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/media?parent=570125"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/categories?post=570125"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/tags?post=570125"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/es\/wp-json\/wp\/v2\/cross-post-tag?post=570125"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}