Courrier des ingénieurs
Épisode 4 : Pythons et pandas, oh là là !

De temps à autre, nous autres ingénieurs système, sommes confrontés à des questions intéressantes qui sortent quelque peu du cadre d'utilisation habituel de JMP . Ces applications sont généralement ingénieuses et nous rappellent souvent que l'exploitation des données ne se limite pas à la résolution de problèmes commerciaux ou techniques. Parfois, il s'agit simplement de problèmes inattendus et complexes. Ces « imprévus » (comme j'aime les appeler) prennent des formes très diverses : problèmes de programmation, analyses intéressantes, visualisations de données… vous voyez l'idée.
Cela fait un moment que je n'ai pas répondu à la rubrique courrier des lecteurs, mais cette question en particulier me semblait vraiment importante. L'outil que j'ai utilisé pour y répondre n'est pas aussi connu qu'il le devrait. C'est donc l'occasion pour moi d'aider un collègue new-yorkais et de vous présenter une fonctionnalité intéressante de JMP, peut-être méconnue.
La question
Mike[JMP],
Souvent, j'ai besoin d'effectuer des regroupements (groupby) pour récupérer, par exemple, la valeur maximale de tous les éléments regroupés par une étiquette donnée, ce qui, en Python Pandas, donnerait quelque chose comme :
df.groupby(['Something', 'Something Else']).max()
Une autre possibilité serait d'utiliser pandas.nlargest avec un groupby, où je souhaiterais par exemple obtenir les 5 premiers résultats d'un groupby.
Après quelques minutes à bidouiller une formule de colonne, j'abandonne et j'exporte les données pour les réimporter plus tard dans JMP. La fonction Tabulate permet plus ou moins de faire cela, mais pas toujours comme je le souhaite. Un guide expliquant comment utiliser JMP comme Pandas me serait donc extrêmement utile, et pourrait également l'être pour JMP, vu la popularité croissante de Pandas.
Merci,
Entaille
Ma réponse
Salut Nick ! Il existe une astuce pour obtenir une plus grande flexibilité avec les formules, similaire à celle de Pandas. Elle consiste à indiquer à JMP les colonnes selon lesquelles vous souhaitez effectuer le regroupement. Pour ce faire, cliquez avec le bouton droit sur le nom de la colonne et sélectionnez Nouvelle colonne de formule > Regrouper par.

Après cela, toutes les colonnes de formule que vous créerez en cliquant avec le bouton droit sur le nom de la colonne et en utilisant Nouvelle colonne de formule > … seront regroupées selon les colonnes de regroupement que vous avez définies.


Ensuite, il suffit de filtrer ou de sélectionner des sous-ensembles à l'aide de filtres de données ou de filtres de données locaux. Dites-moi si cela vous aide !
Meilleur,
M
Pandas : adorables mustélidés ou outils d’analyse de données ?
Bon, pour les néophytes, Pandas n'est pas un adorable mustélidé aux couleurs criardes. Pandas (généralement abrégé en « pd » dans les scripts Python) est un langage de programmation Python dédié à la manipulation et à l'analyse de données. Il offre notamment des structures de données et des opérations pour manipuler des tableaux numériques et des séries temporelles [ source ]. En résumé, il remplit le rôle des fonctionnalités d'organisation et de manipulation des données de JMP (tableaux de données, menus Lignes et Colonnes, etc.) dans l'environnement de programmation Python. Il est donc essentiel aux flux de travail d'analyse de données en Python. Si vous souhaitez exécuter du code Python directement depuis JMP, cet article n'est pas pour vous. Consultez plutôt ce livre blanc . En revanche, si vous cherchez à vous affranchir de la transformation de données en ligne de commande, poursuivez votre lecture.
DataFrames et tableaux de données
Vous êtes toujours là ? Parfait. Le reste de cet article abordera certains points communs entre Pandas et son équivalent dans JMP. Cette liste n'est en aucun cas exhaustive ; elle vise simplement à vous orienter lorsque vous comparez ces deux environnements.
Le premier point que je souhaite aborder concerne le « DataFrame ». Dans Pandas, c'est là que toutes les données sont stockées. À l'instar des tables de données dans JMP, il s'agit essentiellement d'une collection de colonnes de données, chacune ayant un nom (nom de colonne, etc.). Vous effectuez des opérations sur les colonnes et les lignes (transformation, synthèse, etc.), mais vous agissez toujours soit sur le DataFrame dans son ensemble, soit sur une partie de celui-ci.
Dans JMP, le principal conteneur de données est le tableau de données. Vous pouvez manipuler les colonnes et les lignes de la même manière que dans un DataFrame Pandas. Dans les deux cas, vous pouvez gérer les valeurs manquantes dans le tableau de données. Dans JMP, elles sont indiquées soit par une cellule contenant un point (« . ») (pour les données numériques), soit par une cellule vide (pour les données textuelles). Vous pouvez transformer les données, les synthétiser, etc. (nous y reviendrons plus tard). Dans les deux cas, plus vous fournissez d'informations au logiciel sur les données, moins vous aurez de travail préparatoire à effectuer, ce qui m'amène à mon point suivant.
Propriétés des colonnes et types de données
En matière de propriétés de colonnes et de types de données (dtypes dans Pandas), JMP l'emporte haut la main. Pandas hérite la plupart de ses connaissances en types de données d'un autre package Python appelé NumPy, ce qui est un atout. NumPy est un code robuste, mais très limité à cet égard. Il gère environ huit types de données (voir le tableau ci-dessous [ source ]) avec une prise en charge assez limitée des différents formats (il a par exemple du mal à gérer les devises sans aide).
| Type de données |
Type de données |
Scalaire |
Tableau |
Alias de chaînes |
Documentation |
| date et heure prenant en compte le fuseau horaire |
DatetimeTZDtype |
Horodatage |
tableaux.DatetimeArray |
'datetime64[ns, ]' |
Gestion des fuseaux horaires |
| Catégorique |
Type de données catégoriel |
(aucun) |
Catégorique |
'catégorie' |
Données catégorielles |
| période (intervalles de temps) |
Type de période |
Période |
tableaux.PeriodArray |
'période[ ]', 'Période[ ]' |
représentation de l'intervalle de temps |
| clairsemé |
SparseDtype |
(aucun) |
tableaux.SparseArray |
'Sparse', 'Sparse[int]', 'Sparse[float]' |
Structures de données éparses |
| intervalles |
IntervalDtype |
Intervalle |
tableaux.IntervalArray |
'intervalle', 'Intervalle', 'Intervalle[ ]', 'Intervalle[datetime64[ns, ]]', 'Intervalle[timedelta64[ ]]' |
Index d'intervalle |
| entier pouvant être nul |
Type Int64D , … |
(aucun) |
tableaux.IntegerArray |
'Int8', 'Int16', 'Int32', 'Int64', 'UInt8', 'UInt16', 'UInt32', 'UInt64' |
Type de données entier nullable |
Les propriétés des colonnes dans JMP occupent environ 43 pages du livre « Using JMP » . Elles sont bien plus complètes et permettent une excellente reconnaissance des types de données lors de leur importation. Un nouvel utilisateur de JMP appréciera particulièrement le fait que les propriétés des colonnes s'étendent bien au-delà des types de données utilisés par Pandas. JMP peut gérer une multitude de métadonnées qui déclenchent des actions dans tout le logiciel. Certes, il est possible d'associer des attributs à un DataFrame Pandas, mais comme le DataFrame n'est qu'un conteneur, il faut soit implémenter soi-même la gestion de ces attributs, soit espérer qu'elle soit déjà intégrée au package utilisé. Avec JMP, tout cela est déjà fait.
Tabulation, formules de colonnes et regroupement
En réalité, les deux points précédents n'ont pas une grande importance dans le contexte de la question à laquelle je tentais de répondre. Pour nos besoins, le tableau de données/DataFrame n'est qu'un contenant. Les propriétés/types des colonnes peuvent être utiles pour l'analyse, mais, encore une fois, ce n'est pas pertinent pour la question posée. La fonctionnalité de Pandas qui nous intéresse s'appelle GroupBy. Elle permet de segmenter les données en vue d'autres analyses. Voici un exemple rapide utilisant le tableau de données JMP Big Class pour obtenir la taille et le poids moyens des garçons et des filles par âge :
# Import Pandas
import pandas as pd
# Bring in the data
data = pd.read_csv("/Users/mike.anderson@jmp.com/Desktop/Big Class.csv")
# Put the data into a DataFrame
df = pd.DataFrame(data)
# Run the group by, get the means, and show the results
summ_df= df.groupby(['sex','age']).mean()
print(summ_df)
Le résultat ressemble à ceci :
height weight
sex age
F 12 58.600000 100.200000
13 59.000000 95.333333
14 62.600000 96.600000
15 63.000000 102.000000
16 62.500000 113.500000
17 62.000000 116.000000
M 12 57.333333 97.000000
13 61.250000 94.250000
14 65.285714 103.857143
15 65.200000 110.800000
16 68.000000 128.000000
17 69.000000 153.000000
Normalement, les utilisateurs de JMP privilégient les fonctions Summary ou Tabulate pour les transformations de données. Ils peuvent même utiliser l'éditeur de formules pour créer une colonne. Cependant, la table de données (et la liste des colonnes de la plateforme ) recèle une fonctionnalité permettant de réaliser presque toutes les opérations possibles avec Pandas, et bien plus encore. Il s'agit de la possibilité de faire un clic droit sur le nom d'une colonne et de sélectionner « Nouvelle colonne de formule ». Cette fonction est disponible partout où une liste de colonnes est présente ! Vous disposez alors de nombreuses options pour effectuer diverses transformations, comme la combinaison de colonnes, le calcul de sommes cumulées sur les lignes, etc. En soi, bien que pratique, cette fonctionnalité n'a rien de magique. L'intérêt réside plutôt dans l'activation de l'option « Grouper par » pour une colonne dans JMP. Les colonnes de formule créées prendront alors automatiquement en compte les niveaux de la variable de regroupement. Imaginez un instant : vous pouvez créer une colonne de formule n'importe où dans le logiciel, et cette colonne peut être stratifiée en fonction d'une colonne de regroupement.
Prenons l'exemple d'une autre question que j'ai reçue récemment pour illustrer ce que cela signifie :
Exemple : DEUX QUESTIONS POUR LE PRIX D'UNE !!
À peu près au même moment où j'ai reçu la première question, j'en ai reçu une d'un autre client qui souhaitait savoir comment calculer une intégrale numérique (l'aire sous la courbe ou AUC) pour un grand nombre d'échantillons. De plus, il était disposé à me fournir un jeu de données qu'il avait précédemment publié dans un article de la revue Mutagenèse environnementale et moléculaire .
Il s'avère que ce qu'ils souhaitaient faire était facilement réalisable grâce aux indicateurs de regroupement et aux colonnes de fonction. Voici la procédure (vous pouvez la suivre en utilisant les données du site public de JMP 
Commençons par représenter graphiquement les données . Les détails de l'étude ne sont pas essentiels à cette discussion, bien qu'elle soit intéressante à lire . En résumé, il s'agit d'une vaste collection de substances chimiques à différentes concentrations (Conc. (µM)) et d'une série de réponses génétiques. Pour notre exercice, les chercheurs s'intéressent au calcul de l'AUC pour chaque réponse génétique. Voici un aperçu dans Graph Builder avec un sélecteur de colonnes :
La première étape du calcul de l'AUC consiste à configurer le regroupement. Faites un clic droit sur la colonne « Produit chimique », sélectionnez « Nouvelle colonne de formule », puis « Grouper par ». Répétez l'opération pour la colonne « Biomarqueur ». L'ordre est important : nous regroupons d'abord par « Produit chimique », puis par « Biomarqueur » au sein de la colonne « Produit chimique ». Ensuite, il suffit d'utiliser la « Nouvelle colonne de formule » dans le tableau de données pour effectuer le calcul.

Pour plus de clarté, j'ai détaillé chaque étape dans des colonnes distinctes. Et, si cela vous intéresse, j'utilise la méthode des trapèzes pour la somme de Riemann .
Bien, reprenons le calcul. Il nous faut d'abord la distance entre chaque point de l'axe des abscisses (la variation de x point par point). Sélectionnez la colonne Conc (µm), faites un clic droit sur son titre et choisissez Nouvelle colonne de formule > Ligne > Différence. Ouvrez ensuite la formule dans la nouvelle colonne créée par JMP. Elle devrait ressembler à ceci :

Notez que JMP gère les calculs entre les lignes et a ajusté la formule pour qu'elle se réinitialise lorsqu'il détecte un nouveau produit chimique ou un nouveau type de biomarqueur.
Ensuite, nous avons besoin de la valeur moyenne entre chaque point de données et le précédent. Faites un clic droit sur l'en-tête de colonne et sélectionnez Nouvelle formule > Colonne > Ligne > Décalage. Ouvrez la formule et modifiez-la légèrement afin qu'elle calcule la différence entre les lignes et non pas seulement la valeur de la ligne précédente. Ceci est illustré dans cette capture d'écran :

Ces deux colonnes (que j'ai renommées dx et toi dans le tableau de données) doivent être multipliées pour obtenir l'aire d'un segment. Sélectionnez les deux colonnes, puis faites un clic droit sur le nom de l'une d'elles. Sélectionnez Nouvelle colonne de formule > Combiner > Produit. La nouvelle colonne nous donne l'aire approximative sous la courbe, c'est-à-dire la portion de la courbe comprise entre chaque point de données et le suivant. J'ai renommé cette colonne iAUC (pour AUC instantanée) dans le tableau de données.

La dernière étape consiste à additionner les valeurs de chaque section. Pour ce faire, cliquez avec le bouton droit sur la colonne iAUC et sélectionnez Nouvelle colonne de formule > Ligne > Somme cumulative. Comme nous avons sélectionné les colonnes de regroupement au début de l'exercice, le total est réinitialisé pour chaque échantillon de l'ensemble de données.

À partir de là, nous pouvons utiliser les fonctions Tabulate ou Summary pour créer un tableau présentant les valeurs maximales de chaque échantillon (l'aire totale approximative sous la courbe). Voici un exemple pour un produit chimique courant :

Réflexions finales
Et voilà ! Vous pouvez facilement reproduire le comportement de Pandas en utilisant les structures existantes dans JMP. Il suffit d'utiliser la variable Group By et le tour est joué. Nul besoin de faire appel à des spécialistes, même les plus malvoyants.
Note de la rédaction :Avez-vous lu leautres articles de notre série Courrier des ingénieursDécouvrez comment Mike aide un utilisateur qui utilisaitJMPdécider de souscrire ou non à un service de déneigement et développer des visualisations uniques pour les programmes éducatifs STEAM.