La méthode apply() de Pandas est l'approche la plus courante pour appliquer une fonction le long d'un axe d'un DataFrame/Series.

Illustration de la méthode apply() de Pandas pour appliquer une fonction le long d'un axe d'un DataFrame

D'après mon expérience, la plupart des utilisateurs de Pandas sont convaincus qu'apply() est une méthode vectorisée.

Autrement dit, ils pensent qu'apply() opère efficacement, élément par élément, comme les autres opérations vectorisées de Pandas.

Mais c'est FAUX.

Contrairement à cette croyance répandue, chaque utilisateur de Pandas DOIT savoir que la méthode apply() n'est PAS vectorisée.

En réalité, c'est simplement une boucle for Python déguisée, qui n'offre aucune des optimisations liées à la vectorisation auxquelles on pourrait s'attendre.

Équivalence entre la méthode apply() de Pandas et une boucle for Python

Résultat : le code s'exécute toujours à la vitesse native de Python. Autrement dit, lentement.

Quelles sont les solutions ?

Une solution consiste à éliminer la méthode apply() en utilisant une approche vectorisée à la place.

Mais je comprends que parfois, trouver une approche vectorisée n'est pas simple.

Une autre solution que je trouve pratique est de paralléliser la méthode apply() en utilisant des bibliothèques tierces optimisées.

L'image ci-dessous compare le run-time de Pandas apply() avec quatre alternatives qui supportent la parallélisation :

Graphique comparant le run-time de Pandas apply() et de quatre alternatives parallélisées

Il est évident que la méthode apply() de Pandas n'est pas la façon optimale d'appliquer une fonction. C'est même la plus lente des cinq.

Il y a deux raisons à cela :

  1. Pandas s'exécute TOUJOURS sur un seul cœur du CPU. Il ne possède donc aucune capacité de parallélisation qu'il pourrait exploiter.

Illustration : Pandas s'exécute toujours sur un seul cœur du CPU, sans parallélisation
  1. La méthode apply() de Pandas n'est pas vectorisée. Elle ne possède donc aucune capacité de vectorisation non plus.

Honnêtement, si les quatre bibliothèques externes présentées dans le visuel ci-dessus ne possèdent pas non plus de capacités de vectorisation, elles exploitent en revanche la parallélisation.

Illustration : la méthode apply() de Pandas n'est pas vectorisée, sans capacité de vectorisation

C'est comme ça qu'on observe une amélioration massive du run-time en les utilisant.

Note bien ici que même si mapply() est la plus rapide dans cet exemple, cela ne signifie pas qu'elle le sera toujours. Pense à faire un benchmark sur ton propre dataset d'abord.

De plus, je sais que la méthode add_row() que j'ai utilisée dans l'image ci-dessus peut facilement être vectorisée. J'ai choisi cet exemple particulier uniquement par souci de simplicité.

En guise de mot de la fin, retiens que ta première tentative doit TOUJOURS être d'écrire des opérations vectorisées.

N'envisage ces bibliothèques tierces que lorsque tu ne vois aucune possibilité d'écrire du code vectorisé, et que tu n'as pas d'autre choix que d'utiliser apply().

Pour démarrer avec ces bibliothèques :

👉 À toi : Quelles autres techniques utilises-tu couramment pour optimiser les opérations Pandas ?

Envie d'aller plus loin ? DataXp t'attend : formations et parcours pour progresser en data science, machine learning et IA.


Commentaires

Avatar

ou participer

À lire ensuite

Des shots dans la même veine, à lire entre deux tâches.

Voir tous les shots
caret-right