{"id":550101,"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-02-28T12:19:58","modified_gmt":"2025-02-28T11:19:58","slug":"polars-vs-pandas","status":"publish","type":"pycharm","link":"https:\/\/blog.jetbrains.com\/fr\/pycharm\/2024\/07\/polars-vs-pandas\/","title":{"rendered":"Polars vs. pandas : quelles sont les principales diff\u00e9rences ?"},"content":{"rendered":"<p>Si vous avez suivi les avanc\u00e9es des dataframes en Python, vous avez sans doute entendu parler de <a href=\"https:\/\/www.pola.rs\/\" target=\"_blank\" rel=\"noopener\">Polars<\/a>, la puissante biblioth\u00e8que de dataframes con\u00e7ue pour travailler avec de grands jeux de donn\u00e9es.<\/p>\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"2560\" height=\"1440\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/08\/Preview-page-1280x720-2x-1.jpg\" alt=\"\" class=\"wp-image-384206\"\/><\/figure>\n\n\n<p>Contrairement aux autres biblioth\u00e8ques pour les grands jeux de donn\u00e9es tels que <a href=\"https:\/\/spark.apache.org\/\" target=\"_blank\" rel=\"noopener\">Spark<\/a>, <a href=\"https:\/\/www.dask.org\/\" target=\"_blank\" rel=\"noopener\">Dask<\/a> et <a href=\"https:\/\/www.ray.io\/\" target=\"_blank\" rel=\"noopener\">Ray<\/a>, Polars est con\u00e7ue pour \u00eatre utilis\u00e9e sur une seule machine, ce qui peut amener \u00e0 la comparer \u00e0 <a href=\"https:\/\/pandas.pydata.org\/\" target=\"_blank\" rel=\"noopener\">pandas<\/a>. Toutefois, Polars pr\u00e9sente de nombreuses diff\u00e9rences significatives avec pandas, notamment en ce qui concerne la fa\u00e7on dont elle g\u00e8re les donn\u00e9es et les cas dans lesquels son utilisation est optimale. Dans cet article, nous allons examiner les d\u00e9tails techniques qui diff\u00e9rencient ces deux biblioth\u00e8ques de dataframes, ainsi que les points forts et les limites de chacune.<\/p>\n<p>Si vous souhaitez aller plus loin, vous pouvez \u00e9couter notre entretien avec <a href=\"https:\/\/github.com\/ritchie46\" target=\"_blank\" rel=\"noopener\">Ritchie Vink<\/a>, le cr\u00e9ateur de Polars, disponible ci-dessous !<\/p>\n\n\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\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"What is Polars?\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/QfLzEp-yt_U?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n<h2 class=\"wp-block-heading\">Pourquoi utiliser Polars plut\u00f4t que pandas ?<\/h2>\n<p>La r\u00e9ponse se r\u00e9sume en un mot : performances. Polars a \u00e9t\u00e9 construit d\u00e8s le d\u00e9part pour offrir une vitesse incomparable et peut ex\u00e9cuter des op\u00e9rations courantes de 5 \u00e0 10 fois plus rapidement que pandas. De plus, les besoins en m\u00e9moire pour les op\u00e9rations avec Polars sont nettement inf\u00e9rieurs \u00e0 ceux des pandas : pandas requiert de 5 \u00e0 10 fois plus de RAM que la taille du jeu de donn\u00e9es, contre 2 \u00e0 4 fois avec Polars.<\/p>\n<p>Vous pouvez consulter une comparaison des performances de Polars avec celle des autres biblioth\u00e8ques de dataframes <a href=\"https:\/\/duckdblabs.github.io\/db-benchmark\/\" target=\"_blank\" rel=\"noopener\">ici<\/a>. Comme vous pouvez le constater, Polars est de 10 \u00e0 100 fois plus rapide que pandas pour les op\u00e9rations courantes et se distingue de mani\u00e8re g\u00e9n\u00e9rale comme \u00e9tant l&#8217;une des biblioth\u00e8ques de dataframes les plus rapides. De plus, par rapport \u00e0 pandas, elle peut g\u00e9rer des jeux de donn\u00e9es plus grands avant que des erreurs dues \u00e0 l&#8217;insuffisance de m\u00e9moire ne se produisent.<\/p>\n<h2 class=\"wp-block-heading\">Pourquoi Polars est-elle si rapide ?<\/h2>\n<p>Ces r\u00e9sultats sont tr\u00e8s impressionnants et vous vous demandez peut-\u00eatre : comment Polars peut atteindre ces performances sur une seule machine ? La biblioth\u00e8que a \u00e9t\u00e9 con\u00e7ue d\u00e8s le d\u00e9part dans un souci de performance et plusieurs facteurs expliquent son efficacit\u00e9.<\/p>\n<h3 class=\"wp-block-heading\">Une biblioth\u00e8que \u00e9crite en Rust<\/h3>\n<p>L&#8217;un des faits les plus connus concernant Polars est qu&#8217;elle a \u00e9t\u00e9 \u00e9crite en <a href=\"https:\/\/numpy. org\/\" target=\"_blank\" rel=\"noopener\">Rust<\/a>, qui est un langage de bas niveau quasiment aussi rapide que C et C++. Pandas s&#8217;appuie quant \u00e0 elle sur des biblioth\u00e8ques Python, parmi lesquelles <a href=\"https:\/\/numpy.org\/\" target=\"_blank\" rel=\"noopener\">NumPy<\/a>. Bien que le c\u0153ur de NumPy soit \u00e9crit en C, il reste limit\u00e9 par des probl\u00e8mes inh\u00e9rents \u00e0 la mani\u00e8re dont Python g\u00e8re certains types en m\u00e9moire, tels que les cha\u00eenes pour les donn\u00e9es cat\u00e9gorielles, ce qui r\u00e9sulte en de mauvaises performances lors du traitement de ces types (vous pouvez lire <a href=\"https:\/\/wesmckinney.com\/blog\/apache-arrow-pandas-internals\/\" target=\"_blank\" rel=\"noopener\">ce tr\u00e8s bon article de blog<\/a> de <a href=\"https:\/\/wesmckinney.com\/\" target=\"_blank\" rel=\"noopener\">Wes McKinney<\/a> pour plus de d\u00e9tails \u00e0 ce sujet).<\/p>\n<p>L&#8217;un des autres avantages de l&#8217;utilisation de Rust est qu&#8217;il garantit une concurrence s\u00fbre, car il est con\u00e7u pour rendre le parall\u00e9lisme aussi pr\u00e9visible que possible. Polars peut ainsi utiliser tous les c\u0153urs de votre unit\u00e9 centrale en toute s\u00e9curit\u00e9, y compris pour les requ\u00eates complexes impliquant plusieurs colonnes, \u00e0 tel point que Ritchie Vink a d\u00e9crit les performances de Polars comme \u00e9tant \u00ab\u00a0d&#8217;un niveau de parall\u00e9lisme embarassant \u00bb. Cela conf\u00e8re \u00e0 Polars des performances largement sup\u00e9rieures \u00e0 celles de pandas, qui n&#8217;utilise qu&#8217;un seul c\u0153ur pour effectuer les op\u00e9rations. \u00c9coutez cette <a href=\"https:\/\/www.youtube.com\/watch?v=7xcUvzERwx0&amp;ab_channel=PyData\" target=\"_blank\" rel=\"noopener\">excellente intervention<\/a> de Nico Kreiling lors de la PyCon DE 2024, qui explique en d\u00e9tail comment Polars parvient \u00e0 obtenir ces r\u00e9sultats.<\/p>\n<h3 class=\"wp-block-heading\">Une biblioth\u00e8que bas\u00e9e sur Arrow<\/h3>\n<p><a href=\"https:\/\/arrow.apache.org\/\" target=\"_blank\" rel=\"noopener\">Apache Arrow<\/a> est un format de m\u00e9moire ind\u00e9pendant du langage qui contribue \u00e9galement aux performances impressionnantes de Polars. Arrow a \u00e9t\u00e9 co-cr\u00e9\u00e9 par Wes McKinney pour r\u00e9soudre les nombreux probl\u00e8mes qu&#8217;il avait constat\u00e9s avec pandas lorsque que la taille des donn\u00e9es explosait. Il s&#8217;agit \u00e9galement du backend de pandas 2.0, une version plus performante de pandas publi\u00e9e en mars 2024. Toutefois, les backends Arrow des deux biblioth\u00e8ques diff\u00e8rent l\u00e9g\u00e8rement : pandas 2.0 s&#8217;appuie sur PyArrow, tandis que l&#8217;\u00e9quipe Polars a cr\u00e9\u00e9 sa propre impl\u00e9mentation d&#8217;Arrow.<\/p>\n<p>L&#8217;un des principaux avantages d&#8217;Arrow pour la cr\u00e9ation d&#8217;une biblioth\u00e8que de donn\u00e9es est l&#8217;interop\u00e9rabilit\u00e9 qu&#8217;il procure. Arrow a \u00e9t\u00e9 con\u00e7u pour standardiser le format de donn\u00e9es en m\u00e9moire entre les biblioth\u00e8ques et il est d\u00e9j\u00e0 utilis\u00e9 par plusieurs biblioth\u00e8ques et bases de donn\u00e9es importantes, comme vous pouvez le voir <a href=\"https:\/\/arrow.apache.org\/overview\/\" target=\"_blank\" rel=\"noopener\">ci-dessous<\/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\">Cette interop\u00e9rabilit\u00e9<\/a> acc\u00e9l\u00e8re les performances, car elle \u00e9vite d&#8217;avoir \u00e0 convertir les donn\u00e9es dans un format diff\u00e9rent entre les diff\u00e9rentes \u00e9tapes du pipeline de donn\u00e9es (en d&#8217;autres termes, elle \u00e9vite de devoir s\u00e9rialiser et d\u00e9s\u00e9rialiser les donn\u00e9es). Elle utilise \u00e9galement la m\u00e9moire plus efficacement, car deux processus peuvent partager les m\u00eames donn\u00e9es sans avoir besoin de faire une copie. \u00c9tant donn\u00e9 que l&#8217;on estime que la s\u00e9rialisation\/d\u00e9s\u00e9rialisation repr\u00e9sente <a href=\"https:\/\/arrow.apache.org\/faq\/\" target=\"_blank\" rel=\"noopener\">80 \u00e0 90 % des co\u00fbts de calcul<\/a> dans les workflows de donn\u00e9es, le format de donn\u00e9es commun d&#8217;Arrow offre \u00e0 Polars des gains de performances significatifs.<\/p>\n<p>Arrow fournit aussi une prise en charge int\u00e9gr\u00e9e pour davantage de types de donn\u00e9es que pandas. La biblioth\u00e8que pandas \u00e9tant bas\u00e9e sur NumPy, elle g\u00e8re parfaitement les colonnes de valeurs enti\u00e8res et \u00e0 virgule flottante, mais est bien moins efficace avec les autres types de donn\u00e9es. <a href=\"https:\/\/datapythonista.me\/blog\/pandas-20-and-the-arrow-revolution-part-i\" target=\"_blank\" rel=\"noopener\">Par contraste<\/a>, Arrow offre une prise en charge avanc\u00e9e pour les donn\u00e9es date\/heure, bool\u00e9ennes, binaires, et m\u00eame pour les types de colonnes complexes comme celles contenant des listes. De plus, Arrow est capable de traiter les donn\u00e9es manquantes de fa\u00e7on native, alors que cela n\u00e9cessite une solution de contournement dans NumPy.<\/p>\n<p>Enfin, Arrow stocke les donn\u00e9es par colonne, toutes les colonnes sont donc stock\u00e9es dans un bloc de m\u00e9moire continu, quel que soit le type de donn\u00e9es. Non seulement cela facilite le parall\u00e9lisme, mais cela rend aussi la r\u00e9cup\u00e9ration des donn\u00e9es plus rapide.<\/p>\n<h3 class=\"wp-block-heading\">Optimisation des requ\u00eates<\/h3>\n<p>L&#8217;une des autres raisons qui explique les performances de Polars r\u00e9side dans la fa\u00e7on dont elle \u00e9value le code. Pandas utilise <em>l&#8217;ex\u00e9cution imm\u00e9diate (eager)<\/em> par d\u00e9faut et effectue donc les op\u00e9rations dans l&#8217;ordre dans lequel vous les avez \u00e9crites. Polars peut aussi bien utiliser l&#8217;ex\u00e9cution imm\u00e9diate que l&#8217;<em>ex\u00e9cution diff\u00e9r\u00e9e (lazy)<\/em>, dans lquelle un optimiseur de requ\u00eates \u00e9value toutes les op\u00e9rations requises et cartographie la mani\u00e8re la plus efficace d&#8217;ex\u00e9cuter le code. Cela peut inclure, entre autres, la r\u00e9\u00e9criture de l&#8217;ordre d&#8217;ex\u00e9cution des op\u00e9rations ou l&#8217;abandon des calculs redondants. Prenons l&#8217;expression suivante pour obtenir la moyenne de la colonne <code>Number1<\/code> pour chacune des cat\u00e9gories \u00ab A \u00bb et \u00ab B \u00bb dans <code>Category<\/code>.<\/p>\n\n\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\n\n<p>Si cette expression est ex\u00e9cut\u00e9e imm\u00e9diatement, l&#8217;op\u00e9ration <code>groupby<\/code> sera inutilement effectu\u00e9e pour l&#8217;ensemble du DataFrame et ensuite seulement filtr\u00e9e par <code>Category<\/code>. Avec l&#8217;ex\u00e9cution diff\u00e9r\u00e9e, le DataFrame peut \u00eatre filtr\u00e9 et l&#8217;op\u00e9ration <code>groupby<\/code> est effectu\u00e9e seulement pour les donn\u00e9es requises.<\/p>\n<h3 class=\"wp-block-heading\">API expressive<\/h3>\n<p>Enfin, Polars dispose d&#8217;une API extr\u00eamement expressive, ce qui signifie que toute op\u00e9ration que vous souhaitez effectuer peut \u00eatre exprim\u00e9e sous forme de m\u00e9thode Polars. Dans pandas, les op\u00e9rations plus complexes doivent souvent \u00eatre transmises \u00e0 la m\u00e9thode <code>apply<\/code> en tant qu&#8217;expressions lambda. Le probl\u00e8me avec la m\u00e9thode <code>apply<\/code> est qu&#8217;elle boucle sur les lignes du DataFrame et ex\u00e9cute l&#8217;op\u00e9ration de fa\u00e7on s\u00e9quentielle sur chacune d&#8217;elles. La possibilit\u00e9 d&#8217;utiliser des m\u00e9thodes int\u00e9gr\u00e9es vous permet de travailler au niveau des colonnes et de tirer parti d&#8217;une autre forme de parall\u00e9lisme appel\u00e9e SIMD.<\/p>\n<h2 class=\"wp-block-heading\">Dans quels cas continuer \u00e0 utiliser pandas\u00a0?<\/h2>\n<p>Tout cela para\u00eet si g\u00e9nial que l&#8217;on peut se demander si cela vaut la peine de continuer \u00e0 utiliser pandas. Pas si vite ! Mais bien que Polars soit extr\u00eamement efficace pour effectuer des transformations de donn\u00e9es, cela n&#8217;est pas l&#8217;option id\u00e9ale pour l&#8217;exploration de donn\u00e9es ou pour une utilisation dans le cadre de pipelines de machine learning. Dans ces domaines, pandas reste la meilleure solution.<\/p>\n<p>En effet, bien que Polars offre une excellente interop\u00e9rabilit\u00e9 avec d&#8217;autres paquets utilisant Arrow, elle n&#8217;est pas <em>encore<\/em> compatible avec la plupart des packages de visualisation des donn\u00e9es, ni avec les biblioth\u00e8ques de machine learning telles que <a href=\"https:\/\/scikit-learn.org\/stable\/\" target=\"_blank\" rel=\"noopener\">scikit-learn<\/a> et <a href=\"https:\/\/pytorch.org\/\" target=\"_blank\" rel=\"noopener\">PyTorch<\/a>. La seule exception est <a href=\"https:\/\/plotly.com\/\" target=\"_blank\" rel=\"noopener\">Plotly<\/a>, qui permet de cr\u00e9er des graphiques directement depuis les DataFrames Polars.<\/p>\n<p>L&#8217;une des solutions envisag\u00e9es serait d&#8217;utiliser le <a href=\"https:\/\/data-apis.org\/dataframe-protocol\/latest\/index.html\" target=\"_blank\" rel=\"noopener\">Python dataframe interchange protocol<\/a> dans ces packages pour leur permettre de prendre en charge plusieurs biblioth\u00e8ques de dataframes afin d&#8217;d&#8217;\u00e9limininer les probl\u00e8mes de goulots d&#8217;\u00e9trangement pour les workflows de science des donn\u00e9es et de machine learning avec pandas. Toutefois, il s&#8217;agit d&#8217;une id\u00e9e encore relativement nouvelle et il faudra encore patienter avant que ces projets ne soient impl\u00e9ment\u00e9s.<\/p>\n<h2 class=\"wp-block-heading\">Outils pour Polars et pandas<\/h2>\n<p>Apr\u00e8s avoir lu tout cela, vous avez s\u00fbrement envie d&#8217;essayer Polars ! <a href=\"https:\/\/www.jetbrains.com\/fr-fr\/pycharm\/data-science\/\" target=\"_blank\" rel=\"noopener\" data-type=\"link\" data-id=\"https:\/\/www.jetbrains.com\/pycharm\/download\/?section=mac\">PyCharm Professional pour la Science des donn\u00e9es<\/a> offre d&#8217;excellents outils pour travailler avec pandas et Polars dans les notebooks Jupyter. Les dataframes pandas et Polars sont notamment affich\u00e9s avec des fonctionnalit\u00e9s interactives, ce qui permet d&#8217;explorer les donn\u00e9es plus facilement et rapidement.<\/p>\n<p>La possibilit\u00e9 de faire d\u00e9filer toutes les lignes et colonnes du DataFrame sans troncature, d&#8217;obtenir des agr\u00e9gations des valeurs du DataFrame en un clic et d&#8217;exporter le DataFrame dans grand nombre de formats (y compris Markdown !) sont quelques-unes de mes fonctionnalit\u00e9s pr\u00e9f\u00e9r\u00e9es.<\/p>\n<p>Si vous n&#8217;utilisez pas encore PyCharm, vous pouvez l&#8217;essayer gratuitement pendant 30 jours en cliquant sur le lien ci-dessous.<\/p>\n\n\n<p align=\"center\">\n    <a class=\"jb-download-button\" href=\"https:\/\/www.jetbrains.com\/fr-fr\/pycharm\/data-science\/\" target=\"_blank\" rel=\"noopener\">      \n        Commencez votre essai gratuit de PyCharm\n    <\/a>\n<\/p>\n\n\n\n<p><em>Auteur de l&#8217;article original en anglais<\/em> :<\/p>\n\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":1336,"featured_media":550108,"comment_status":"closed","ping_status":"closed","template":"","categories":[952],"tags":[566,8152],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm\/550101"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/types\/pycharm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/users\/1336"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/comments?post=550101"}],"version-history":[{"count":6,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm\/550101\/revisions"}],"predecessor-version":[{"id":550132,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/pycharm\/550101\/revisions\/550132"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/media\/550108"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/media?parent=550101"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/categories?post=550101"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/tags?post=550101"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/cross-post-tag?post=550101"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}