Photo de Pedro Gonzalez sur Unsplash
Il était une fois un étudiant désireux d'apprendre la science des données.
Il a demandé aux gens ce qu'il devait faire et ils lui ont dit d'apprendre les pandas. Il a parcouru le Web à la recherche de cours sur les données, et ils présentaient tous des pandas. L'étudiant a donc appris les pandas, puis a obtenu un emploi dans le milieu universitaire, où tout le monde travaillait avec les pandas.
Il a donc peiné avec des pandas pendant de nombreuses lunes, jusqu'à ce qu'il puisse découper des trames de données dans son sommeil. Quand il eut fini, il rejoignit un camp d'entraînement sur les données : voilà, ils enseignaient aux pandas. Quand il a eu fini, le bootcamp l'a embauché pour enseigner aux pandas.
Puis vint le moment où l'étudiant entra dans sa première entreprise. Son maître voulait qu'il traite certaines données.
"Je vais utiliser des pandas" a déclaré l'étudiant.
« Bon sang, tu le feras ! » dit le maître. « Nous utilisons S—Q—L ici », a-t-il rétorqué en insistant sur chaque lettre d'un coup de bâton.
"Mais... Mais... Verbosité... Laideur... Manque de fonctions... Imbrication sans fin... Et les jointures, les jointures sont horribles !..."
"Si vous ne pouvez pas voir la forêt, alors vous ne devriez pas toucher les arbres" a dit le maître en le frappant sur la tête.
L'élève était éclairé.
Ou alors il pensait; en fait, le coup du maître l'avait tellement étourdi que son jugement en était temporairement altéré.
Plusieurs lunes plus tard, après un retrait douloureux, l'étudiant a compris SQL. À partir de ce moment-là, il n'a plus ressenti le besoin d'utiliser des pandas et le maître ne lui a plus jamais porté de coup.
Le koan ci-dessus est autobiographique, bien que je doive remarquer qu'aucun de mes superviseurs ne m'a jamais frappé (même quand ils auraient dû le faire).
Peu de choses ont changé depuis que j'ai commencé. La plupart des programmes d'études des bootcamps de données comportent un investissement important dans les pandas (aux côtés des ordinateurs portables Jupyter), tandis que SQL est au mieux une réflexion après coup.
Recherchez "science des données" sur Udemy, et vous verrez les meilleurs cours mentionnant Python (qui inclut inévitablement les pandas) et R, parfois même Scala. Très peu d'entre eux mentionnent SQL.
Je pense que c'est mauvais, tant du point de vue de la valeur que du point de vue pédagogique.
Si vous effectuez des analyses standard, SQL est tout simplement un meilleur outil que les pandas. C'est plus simple, plus clair, plus puissant et efficace. C'est aussi plus facile à comprendre, à partager et à reproduire. Il y a une raison pour laquelle c'est la lingua franca de l'analyse de données depuis des décennies.
Si vous vous concentrez sur Pandas au détriment de SQL, vous manquez d'être un praticien des données meilleur et plus efficace.
Bien sûr, il y a des choses que les pandas font mieux, et je les explore brièvement à la fin de l'article. Mais dans l'ensemble, en matière d'analyse pure, SQL est difficile à battre.
Les gens ne remarquent souvent pas que les pandas introduisent une surcharge importante en termes de complexité, d'inefficacité, d'idiosyncrasie et de possibilités de confusion.
Je soupçonne que l'accent excessif mis sur les pandas nuit aux étudiants en données. D'après mon expérience, il y a un point où faire plus de pandas entraîne un anti-apprentissage , c'est-à-dire que la personne devient simplement plus confuse avec le temps.
Les nouveaux étudiants, en particulier, rencontrent des problèmes étranges qui les déroutent et qu'ils compensent par une mémorisation aveugle.
Ils acquièrent également de mauvaises habitudes qu'il est difficile d'abandonner plus tard, comme boucler sur des lignes alors qu'ils pourraient utiliser des opérations de table ; créer des colonnes avec des types mixtes ; enregistrement des données au format CSV ; modifier les données en place ; obstruer la mémoire avec plusieurs copies et tranches de la même trame de données... Je pourrais continuer.
Une partie de cela vient du fait que Python est un langage extrêmement tolérant, ce qui oblige l'utilisateur à ne pas faire de mauvaises choses (comme les pandas Series
avec des types mixtes). Cela vient en partie du fait que les pandas acceptent (mais n'encouragent pas nécessairement) une approche impérative.
Par exemple, si un étudiant souhaite combiner les données de deux tables, rien ne l'empêche d'utiliser cet algorithme :
Boucle sur table1
Pour chaque ligne de table1
, analysez toutes les table2
pour une recherche
Mettre à jour la ligne de table1
à partir des données de table2
Oui, c'est évidemment très mauvais. Mais les débutants ne savent pas mieux.
En revanche, l'approche déclarative de SQL rend plus difficile les mauvaises actions.
La programmation déclarative oblige l'utilisateur à penser en termes de résultat qu'il souhaite voir, plutôt qu'à la manière de le produire . Cela leur donne l'espace dont ils ont besoin pour se concentrer sur la logique derrière leur analyse, plutôt que d'être constamment enlisés par des problèmes et des bugs étranges.
SQL oblige également les étudiants à penser aux tables (c'est-à-dire au modèle relationnel) et aux opérations au niveau des colonnes, ce qui est très bénéfique lorsque leur premier réflexe est de tout boucler.
Enfin, apprendre SQL produit un meilleur retour sur investissement en raison de son universalité et de sa portabilité.
Je ne déteste pas les pandas. C'était mon outil d'analyse de base pendant deux ans, et je l'utilise toujours pour mes projets personnels. Je suis content de voir que les gens l'apprennent.
Mais j'essaie de voir la situation dans son ensemble. Je pense que trop insister sur les pandas au détriment de SQL fait plus de mal que de bien . Surtout quand il s'agit de débutants, qui découvrent les pandas MultiIndex
avant de pouvoir faire un bon GROUP BY
.
Dans la section suivante, j'analyse certains des aspects les plus étranges des pandas et je les compare directement avec SQL.
Le but, encore une fois, n'est pas d'abattre les pandas, mais d'élargir le point de vue du lecteur sur les outils à sa disposition.
Approfondissons.
SELECT * FROM opinionated_comparison WHERE sql > pandas
En une seule instruction, le SELECT
de SQL vous permet de :
Sélectionnez les colonnes souhaitées et l'ordre dans lequel elles doivent être renvoyées.
Créez de nouvelles colonnes basées sur des combinaisons et des transformations de colonnes existantes.
Renommer les colonnes.
Cet exemple sélectionne toutes les colonnes sauf une, puis crée une nouvelle colonne basée sur une combinaison linéaire de deux autres colonnes :
SELECT * EXCEPT (first_name), equity_comp / total_comp * 100 AS percent_equity FROM salaries
La sélection de colonnes pandas permet uniquement de choisir et de classer les colonnes. Si vous souhaitez en renommer ou en transformer certaines, vous avez besoin de plusieurs instructions, et de nombreuses personnes tombent dans l'erreur de transformer des données sur place (voir immuabilité ci-dessous).
Les débutants sont confus car la sélection d'une seule colonne nécessite un ensemble de crochets ( df[”first_name”]
) tandis que la sélection de plusieurs colonnes nécessite un double ensemble de crochets ( df[[”first_name”, "last_name"]]
).
Le plus gros problème que j'ai avec les pandas ici est la notation par points : le fait que vous puissiez sélectionner des colonnes comme celle-ci : df.first_name
.
C'est tellement plus facile que d'utiliser des crochets et des guillemets, alors les gens finissent par le préférer par pure paresse. C'est du moins ce qui m'est arrivé : j'utilise toujours la notation par points automatiquement, même si je sais que c'est mauvais.
Les problèmes apparaissent lorsque vous avez une colonne appelée count
ou shape
ou diff
ou tout autre des nombreux attributs standard d'un dataframe (vous pouvez tous les voir avec dir(df)
).
Lorsque vous essayez d'y accéder avec la notation par points, vous obtiendrez l'attribut au lieu de la colonne et votre code se cassera.
Pandas a donc trois façons de sélectionner des colonnes : deux pour obtenir une seule colonne (dont une est mauvaise mais plus attrayante !) et une troisième pour sélectionner plusieurs colonnes.
En SQL, pour sélectionner des lignes spécifiques, il vous suffit d'utiliser l'instruction WHERE
(voir Filtrage ci-dessous).
La sélection de lignes dans Pandas est... complexe. Pour voir la complexité, consultez le guide de démarrage de l'utilisateur . Ou plongez dans un didacticiel typique de 30 minutes .
Je me limiterai à un seul exemple. Chaque DataFrame a un Index
. L'index par défaut est une suite d'entiers : [0,1,2,3,4,5...]
.
Naturellement, la plupart des gens supposent que l'index représente la cardinalité des lignes. En fait, les chiffres ne sont que des étiquettes catégorielles ! Il peut aussi s'agir de lettres aléatoires comme ['x', 'z', 'a']
. Il n'y a pas de cardinalité implicite.
Pour obtenir une ligne par son index, vous utilisez df.loc
. Mais pour sélectionner par la cardinalité de la ligne, vous utilisez df.iloc
. Avec l'index par défaut, ces deux méthodes donnent le même résultat.
Ce qui ne fait qu'ajouter à la confusion, car à tout moment votre index peut changer en quelque chose de complètement aléatoire comme [7, 2, 2, 'c', True, None]
. Oui, tout cela est autorisé ! Et il n'y a aucune contrainte pour l'empêcher (voir Contraintes ci-dessous).
Imaginez que vous écriviez votre code en supposant que l'index représente la cardinalité des lignes. À présent:
df.loc[7]
renverra la première lignedf.loc[2]
renverra une tranche de trame de données au lieu d'une ligne (car elle se produit plus d'une fois dans l'index)df.loc[None]
renverra une ligne réelle !
Je ne pleure pas, tu pleures.
Et oui : la même méthode peut retourner une valeur scalaire, une ligne ou une tranche de dataframe selon la composition de l'index. Les docs pandas reconnaissent cette folie :
D'autres méthodes, comme l'indexation, peuvent donner des résultats très surprenants. Typiquement, l'indexation avec un scalaire réduira la dimensionnalité . Trancher un
DataFrame
avec un scalaire renverra unSeries
. Découper uneSeries
avec un scalaire renverra un scalaire. Mais avec les doublons [index], ce n'est pas le cas.
Et rappelez-vous, il n'y a aucune contrainte pour empêcher l'index de contenir des doublons. Je ne peux pas commencer à vous dire combien de maux de tête cela m'a causé.
(En plus de toutes les méthodes de sélection que nous avons mentionnées, pandas a également df.at
et df.iat
pour les valeurs uniques. Une autre chose à retenir et à éviter toute confusion.)
En SQL, le filtrage est simple. Écrivez WHERE
, insérez autant d'instructions que vous le souhaitez et enchaînez-les avec des opérateurs logiques. Les crochets vous donnent plus de contrôle sur la structuration des expressions.
Par exemple, la requête suivante filtre les personnes qui ont à la fois plus de 30 ans et qui remplissent au moins l'une des deux conditions suivantes : plus de 5 ans d'ancienneté ou une rémunération en actions inférieure à 50 :
SELECT * from salaries WHERE age > 30 AND (tenure > 5 OR equity_comp < 50)
À quoi cela ressemble-t-il dans Pandas ?
new_df = df[(df["age"] > 30) & ((df["tenure"] > 5) | (df["equity_comp"] < 50))]
Pouah. Amusez-vous à expliquer cela aux débutants.
Certes, vous ne l'écririez probablement pas comme ça parce que c'est trop moche. Vous exécuteriez le filtrage dans plusieurs instructions : ce qui signifie plus de lignes de code, de variables et de répétitions.
Les filtres Pandas sont basés sur une méthode appelée indexation booléenne . Chaque opération de filtrage se déroule en deux étapes :
Vous prenez une Series
(c'est l'objet colonne) et exécutez chaque élément à travers un test booléen. Le transformant ainsi en une nouvelle Series
composée de valeurs booléennes (vrai ou faux).
Vous sélectionnez la trame de données avec cette colonne, qui finit par exclure les lignes où la Series
booléenne contient une valeur fausse.
Remarquez l'hypothèse cachée ici? La Series
utilisée pour filtrer et la trame de données filtrée doivent partager le même index, dans le même ordre. Ce n'est pas toujours garanti.
En pratique, l'indexation booléenne signifie que lorsque vous filtrez, vous devez toujours répéter la variable dataframe, par exemple salaries[salaries["cash_comp"] > 20]
. C'est très ennuyeux lorsque vous écrivez beaucoup de code ! Voir l'exemple ci-dessus : la variable dataframe est référencée 4 fois.
Je peux aussi dire par expérience que l'indexation booléenne n'est pas facile à comprendre pour les débutants. Certaines personnes ne comprennent jamais du tout le mécanisme sous-jacent. Ils mémorisent simplement le modèle de codage.
(La méthode df.query()
semble fournir une meilleure méthode de filtrage .)
Aucune plainte majeure ici. Mais SQL est définitivement plus proche de l'anglais. Ces deux sont équivalents :
SELECT AVG(cash_comp), SUM(tenure) FROM salaries GROUP BY department
grouped_df = df.groupby('department').agg({"cash_comp": np.mean, "tenure": np.sum})
SQL a un type de jointure. Cela s'appelle JOIN
. Bien sûr, il peut être gauche/droite et intérieur/extérieur, mais l'utilisation est assez simple.
Pandas a deux méthodes : join
et merge
. Je n'ai jamais compris pourquoi nous avions besoin de deux. join
est censé fonctionner sur les index, merge
est censé fonctionner sur n'importe quelle colonne.
Mais si vous regardez les docs [ 1 ][ 2 ] ils semblent chacun prendre en charge les index et les colonnes. Je suis confus. (Si vous avez des doutes, je suggérerais de toujours choisir la merge
car la join
est plutôt une méthode héritée.)
SQL rend très facile le JOIN basé sur une chaîne de conditions logiques, telles que : rejoindre par rôle, mais seulement si le salaire à Londres est supérieur à celui de Washington, ou si la personne a une ancienneté plus longue.
SELECT * FROM london_hq lhq JOIN washington_hq whq ON lhq.role = whq.role AND (lhq.salary > whq.salary OR lhq.tenure > whq.tenure)
Autant que je sache, ce n'est pas possible avec les pandas. Lors de la jointure (ou de la fusion), vous ne pouvez utiliser que la condition d'égalité.
Vous devez donc d'abord exécuter le JOIN on role
, garder une trace de l'origine de chaque colonne, puis filtrer sur le résultat.
Cependant, je dirais que ces conditions appartiennent à juste titre au JOIN et ne sont pas moins pertinentes pour ne pas utiliser la comparaison d'égalité.
L'un des principaux avantages de SQL est que chaque colonne a un type bien défini. De plus, les colonnes ne sont pas autorisées à avoir des types mixtes. Cela évite beaucoup de bugs et de maux de tête à long terme.
Lorsque vous chargez des données dans pandas, la plupart des colonnes sont automatiquement typées en tant object
. Cela peut signifier l'une des trois choses suivantes :
La colonne ne contient que des chaînes
La colonne contient des objets Python qui ne sont pas un type de données primitif, par exemple une liste ou un dictionnaire
La colonne contient des types mixtes
Lorsque vous voyez le type de données d' object
, vous ne savez jamais quel est le cas. Je trouve cela très ennuyeux.
Contrairement à SQL, vous pouvez charger des données avec des types mixtes dans pandas : elles seront simplement typées comme object
.
Pandas ne vous oblige pas à spécifier un schéma et à vous y tenir. Cela vous donne une prime de vitesse lorsque vous démarrez, mais vous le payez souvent très cher dans les futurs bogues et confusions.
Ceci est particulièrement problématique pour les débutants qui ne sont pas conscients des pièges courants. Par exemple, lorsque je travaillais avec Pandas, je tentais souvent une opération datetime, pour me rendre compte que la colonne datetime était constituée de chaînes (donc classées comme object
). Je ferais naïvement ceci :
df['Date'] = df['Date'].astype('datetime64[ns]')
Et passer à autre chose, pour découvrir bien plus tard que l'analyseur de date de Pandas avait mal lu mes chaînes et que les dates n'avaient aucun sens.
Soyons honnêtes : la plupart des gens stockent leurs dataframes au format CSV. Les étudiants Pandas sont les bienvenus, voire encouragés à le faire. C'est une mauvaise idée!
Bien sûr, les fichiers CSV sont lisibles par l'homme et... leurs avantages s'arrêtent là. Leurs inconvénients sont :
Lors de la conversion au format CSV, vous perdez toutes les informations sur les types de schéma et de colonne. Tout revient au texte.
Les fichiers CSV sont sujets aux erreurs de formatage, de corruption et d'analyse.
Les CSV sont difficiles à compresser, ce qui augmente les coûts de stockage.
Le format CSV est sous-spécifié , ce qui signifie que différents programmes créent des fichiers CSV de différentes manières et qu'il incombe à l'utilisateur de comprendre comment les analyser. Cela peut rapidement se transformer en une expérience infernale, comme tout professionnel des données en attestera.
La perte de schéma est généralement le plus gros problème pour les personnes qui travaillent dans les pandas. C'est une situation courante :
Votre travail commence par un CSV. À condition que vous ayez trouvé le bon formatage, l'encodage, la spécification des caractères de citation et le reste des nombreux arguments de read_csv
de pandas, vous le chargerez dans une trame de données. Vous devez maintenant passer du temps à explorer les colonnes, à convertir chaque colonne dans le type correct, à vous occuper des bogues qui apparaissent dans le processus et à vérifier que le résultat final a du sens. (Ou vous pourriez commencer à travailler immédiatement et faire face à de nombreux bogues plus tard).
Une fois votre travail terminé, vous disposez d'un nouveau dataframe. Qu'est-ce que tu vas faire avec ça? Pourquoi, enregistrez-le au format CSV. Maintenant, tout votre travail précédent sur la définition de schéma a disparu, puisque le dataframe est vidé en texte.
Vous devez charger le nouveau dataframe pour un autre workflow. Cela signifie charger le CSV que vous venez de vider. J'espère que vous avez écrit des fonctions capables de restaurer le schéma avec succès, sinon vous devrez recommencer le travail (à condition que vous vous souveniez de ce que chaque colonne était censée faire).
Vous souhaitez partager le CSV avec un ami ou le publier sur GitHub ? Vous feriez mieux de partager le code qui peut réimputer le schéma et d'espérer qu'ils voudront et pourront l'exécuter. Ou ils se retrouveront avec une masse de texte et devront répéter tout le travail d'imputation de schéma à partir de zéro.
Cela semble absurde ? J'ai vu cela fait un nombre incalculable de fois . J'ai fait ça moi-même ! Mais maintenant je me demande : pourquoi apprenons-nous aux gens à travailler comme ça ? Qu'est-ce qui justifie tant de folie et de cruauté ?
Il y a deux solutions ici.
Si vous avez vraiment besoin de travailler dans les pandas, exportez vos dataframes dans Parquet.
Ou vous pouvez travailler en SQL et vous épargner tous les ennuis. Après tout, une base de données est le meilleur endroit pour stocker des données.
Demandez-vous : pourquoi ai-je besoin d'une couche de fichiers ? Si vous lisez simplement des données, les traitez puis stockez les résultats, ce n'est probablement pas le cas. Charger depuis la base de données, travailler dans la base de données, enregistrer dans la base de données. C'est si simple. Besoin de partager des données en externe ? Exportation en Parquet.
Le monde n'a pas besoin de plus de CSV.
Remarque : certaines personnes essaient de résoudre le problème du schéma en décapant leurs dataframes . C'est une idée terrible .
Le marinage est inefficace et peu sûr (n'ouvrez jamais un mariné en qui vous n'avez pas confiance !). Une trame de données marinée ne peut être ouverte qu'à l'intérieur de Python, et cela doit se produire dans le même environnement de bibliothèque (dont l'utilisateur peut ne rien savoir). Si les pandas qui lisent le cornichon sont une version différente de celle des pandas qui l'ont écrit, le fichier peut être illisible !
SQL utilise des valeurs NULL pour indiquer les données manquantes. Vous pouvez facilement filtrer les valeurs nulles.
SELECT * FROM salaries WHERE equity_comp IS NOT NULL AND cash_comp IS NOT NULL
Dans Pandas, les valeurs manquantes peuvent être l'une de ces valeurs :
Python natif None
(que Pandas affiche comme None
mais traite comme nan
)
numpy.nan
pandas.NA
pandas.NaT
(pour les dates et heures)
Concentrons-nous sur numpy.nan
qui est le plus courant :
Le type de cet objet est float
, alors oubliez de le détecter avec des vérifications de type.
C'est vrai, alors oubliez les tests booléens. bool(np.nan)
est True
.
Il échoue au test d'égalité, car numpy.nan == numpy.nan
est faux. nan
n'est pas égal à lui-même !
L'utilisation de nan
dans une opération ne lève pas d'exception, cela signifie simplement que le résultat est nan
.
N'est-ce pas amusant?
La seule façon de détecter un nan
est d'utiliser pandas.isna()
. C'est bien, une fois que vous avez lu la documentation et oublié tous vos instincts pythoniques. Pourtant, ce comportement est extrêmement déroutant pour les débutants.
Voici comment répliquer la requête ci-dessus dans Pandas :
new_df = df.dropna(subset=["equity_comp", "cash_comp"])
Les contraintes sont importantes en SQL. Ils vous permettent de spécifier des règles qui garantissent la sécurité et la cohérence de vos données. Par exemple, la clé primaire, qui sert d'identifiant unique pour chaque ligne, doit être unique et non nulle.
Pandas n'a rien de tel.
La chose la plus proche d'une clé primaire dans les pandas est l'index. Malheureusement, la valeur d'index peut être à la fois répétée et nulle (oui, vous pouvez avoir un index avec des valeurs None
).
Les utilisateurs travaillent souvent avec l'hypothèse implicite que l'index est une clé primaire, une idée renforcée par le fait que l'index par défaut est composé d'entiers : [0,1,2,3,4...]
. Par conséquent, les gens ont tendance à utiliser l'index pour référencer des lignes spécifiques, par exemple df.loc[2]
.
C'est un acte de foi insensé. Cela devient évident lors de la concaténation ou de la fusion de différentes trames de données. Il arrive souvent que des index similaires soient mélangés et que vous obteniez un index qui ressemble à ceci : [0,1,2,2,2,3...]
.
Pandas ne lance aucun avertissement à ce sujet, vous ne vous en rendez donc pas compte au début. Mais la prochaine fois que vous utiliserez df.loc[2]
, votre code se cassera car au lieu d'une seule ligne, il renverra désormais une trame de données avec trois lignes.
De nombreuses larmes couleront avant que vous ne compreniez que vous devez exécuter reset_index()
sur le dataframe fusionné afin que chaque ligne obtienne à nouveau une valeur unique.
De plus, les contraintes SQL vous permettent d'effectuer des vérifications au moment de l'écriture. Si vous essayez d'insérer une valeur nulle dans une colonne qui porte la contrainte NOT NULL
, vous obtenez une exception et la mauvaise écriture ne se produit pas. Pandas n'autorise l'exécution de vérifications qu'en lecture. Autrement dit, si vous vous souvenez de le faire.
C'est surtout un point pédagogique. Pandas, c'est bien connu, permet et même encourage les opérations vectorisées (où tous les éléments d'une série sont accédés en parallèle).
Mais beaucoup de gens qui travaillent en Python ne pensent pas automatiquement comme ça. Ils ont commencé par apprendre des boucles et maintenant, par Guido , ils veulent utiliser ces boucles.
Lorsqu'ils débutent avec les pandas, ils découvrent rapidement les méthodes iterrows
et itertuples
, qui leur permettent de boucler le dataframe par lignes.
Presque inévitablement, ils retombent dans des schémas en boucle, car rien ne les oblige à penser en vecteurs. Cela les amène à écrire un code terrible qui s'exécute très lentement.
J'ai commencé à me concentrer sur SQL après une longue expérience avec les pandas. Chaque fois que j'étais confronté à un problème SQL, mon instinct était de trouver une solution en boucle. Malheureusement, SQL ne m'a pas permis de le faire.
Sa syntaxe déclarative m'a obligé à penser en termes d'opérations de colonne, de JOIN et de fonctions de fenêtre. Peu à peu, j'ai construit un nouvel ensemble de modèles mentaux qui ont fait de moi un meilleur analyste.
Je pense que les apprenants devraient développer leur confiance en manipulant des données en SQL avant de commencer avec les pandas. Ils seront mieux équipés pour comprendre quand le bouclage par rangée est inévitable, ce qui est rare.
Vous chargez une dataframe en mémoire. Vous devez modifier cette trame de données. Le modifiez-vous sur place ou créez-vous une copie ? Faut-il mettre à jour les colonnes existantes ou en créer de nouvelles ?
Que faire si vous avez besoin de créer plusieurs tranches de dataframe, puis de travailler sur chaque tranche ? Devez-vous stocker chaque tranche dans une variable distincte ou utiliser la même variable pour contenir différentes tranches à tour de rôle ?
Lorsque les gens travaillent dans les pandas, ils ont tendance à faire toutes ces choses en même temps. Il devient rapidement difficile de garder une trace de toutes les variables qui contiennent des dataframes, des slices de dataframes et des slices de slices, et de savoir comment les données ont été ajoutées ou modifiées.
(Je n'écris pas toujours des pandas, mais quand je le fais, j'obtiens le paramètre avec avertissement de copie .)
Et comme la plupart des gens utilisent des pandas avec des ordinateurs portables, ces problèmes s'aggravent avec les pièges typiques des ordinateurs portables et finissent par causer d'énormes maux de tête.
C'est l'une des raisons pour lesquelles je pense que les pandas ne sont pas la meilleure option pour l'analyse des données.
Lors du traitement de données en SQL, vous ne modifiez pas les données d'origine. L'instruction UPDATE
n'est pas utilisée dans les analyses. Au lieu de cela, vous créez des pipelines de tables et de vues qui représentent différentes sélections.
Lorsque vous devez enregistrer vos résultats, vous créez de nouvelles tables (ou ajoutez des lignes aux tables cibles existantes, mais sans modifier ni supprimer les lignes précédentes). Cela respecte le principe d' immuabilité : ne jamais modifier ou supprimer les données sources. Il rend votre processus sûr, transparent et facile à reproduire.
Oui, vous pouvez respecter l'immuabilité chez les pandas, mais il n'est pas évident que vous deviez le faire, et beaucoup de gens n'apprennent jamais à le faire. Ce que vous voyez généralement, c'est l'immuabilité au niveau des fichiers : les gens chargent généralement un CSV et génèrent un nouveau CSV. Mais pour le travail qui se passe entre les deux ? Tout va.
(La plupart des méthodes pandas sont théoriquement "pures" car elles renvoient une nouvelle trame de données au lieu de modifier la précédente. Mais elles fournissent toutes l'option inplace
qui modifie une trame de données en place. Et les gens l'utilisent avec enthousiasme.)
Si vous travaillez sérieusement avec des pandas, vous finirez par atteindre un mur de performances. Les données que vous analysez sont tout simplement trop volumineuses ou vos besoins de traitement sont trop élevés.
J'ai souvent vu cela lorsque je faisais des recherches sur les pandas. Lorsque cela s'est produit, mes collègues et moi allions sur Google "rendre les pandas plus rapides" et trouvions d'innombrables articles sur ce sujet brûlant, qui proposaient à leur tour d'innombrables hacks, optimisations et bibliothèques PyPI qui promettaient de faire l'affaire.
Si vous êtes dans cette situation, n'hésitez pas à consulter les ressources disponibles. Surtout ceux qui expliquent commentmieux utiliser les pandas . Mais ne placez pas vos espoirs trop haut. Il y a des limites strictes à ce que les pandas peuvent faire. Ce n'est pas grave : il n'a pas été conçu pour être la fin de toutes les analyses de données.
Les deux meilleures alternatives lorsque vous devez faire évoluer vos charges de travail de données sont :
PySpark . Spark est un moteur d'analyse à grande échelle et de traitement de données parallélisé. PySpark vous permet de l'exploiter avec Python et utilise une syntaxe qui rappelle les pandas. Il a même une API pandas.
Entrepôt de données . Un système pour stocker et analyser des données à très grande échelle (pensez aux téraoctets et aux pétaoctets). Les entrepôts de données modernes s'exécutent dans le cloud afin que vous puissiez tirer parti de la puissance des systèmes distribués sans gérer de serveurs. BigQuery, la solution d'entrepôt de données de Google Cloud, peut traiter 100 milliards de lignes ou 7 téraoctets de données en 30 secondes . Les entrepôts de données fonctionnent généralement avec SQL. (Si vous souhaitez essayer BigQuery gratuitement, j'en ai parlé ici. )
Je ne veux pas que tu évites les pandas. C'est un outil génial qui vaut vraiment la peine d'être appris.
Il y a des cas où pandas est un meilleur choix que SQL. Je ne vais pas entrer dans les détails ici, mais voici une liste rapide :
Lors de l'intégration avec d'autres flux de travail Python, par exemple, vous faites de l'apprentissage automatique ou vous souhaitez utiliser une bibliothèque de visualisation Python.
Lorsque vous avez besoin de statistiques rapides. La méthode describe()
est très utile.
Lorsque vous avez besoin d'effectuer une analyse rapide, sans vous soucier de l'échelle ou de la reproductibilité. Bien qu'Excel ou Google Sheets puissent tout aussi bien fonctionner.
Si vous créez des applications Python. Les pandas pourraient être le moyen le plus rapide de passer d'une structure de données arbitraire à une table, et vice versa.
Lorsque vous avez réellement besoin de workflows et de boucles impératifs. Par exemple, la construction de simulations de Markov.
Lorsque vous devez écrire ou réutiliser des fonctions inhabituelles. Pandas est excellent pour appliquer des fonctions Python arbitraires.
Si vous avez un flux de travail hautement dynamique et paramétré.
J'espère que cet article vous a incité à réfléchir plus profondément à SQL et aux pandas, ainsi qu'à leurs forces et faiblesses relatives.
Je pense que la tendance actuelle en matière de données est allée trop loin en faveur des pandas et que vous ignorez SQL à vos risques et périls.
Voici mon conseil :
Si vous êtes un apprenant : étudiez SQL et apprenez à l'utiliser pour vos analyses. Vous ne le regretterez pas.
Si vous êtes un concepteur de programmes : noyez vos étudiants dans SQL jusqu'à ce qu'ils rêvent dans des tableaux et parlent en majuscules. C'est un amour dur et ils vous détesteront pour cela, mais le jour où ils comprendront. (Ne les frappez pas sur la tête cependant.)
Si vous êtes un mentor : essayez de sevrer progressivement vos élèves de Pandas et encouragez-les à tenter des problèmes en SQL.
J'aimerais engager une conversation. N'hésitez pas à laisser un commentaire, m'écrire un e-mail ou m'ajouter sur LinkedIn .