Cette présentation décrit les mises à jour importantes apportées à la prise en charge de Python dans JMP 18, offrant une intégration bien plus étroite avec Python et une expérience utilisateur nettement améliorée. Avec JMP 18, vous pourrez :
Les fonctionnalités JMP accessibles via Python s'étendront progressivement, mais l'accent est actuellement mis sur les fonctions critiques et la prise en charge des données en mémoire. Cette présentation vous permettra de découvrir les changements et leurs raisons d'être, ainsi que les nouvelles fonctionnalités offertes aux utilisateurs de JMP. L'extensibilité et l'importation de données grâce à des packages Python externes seront abordées, et l'accès aux GPU via l'interface Python à l'aide de ces packages sera démontré.
Bonjour, je suis Paul Nelson. Je suis ici pour vous parler de JMP, de Python et de nos prochaines étapes. Suite à une présentation l'année dernière, nous avons décidé de passer à l'étape supérieure. JMP et Python pouvaient être améliorés, et c'est ce dont je vais vous parler.
Le principal défi rencontré par les clients de JMP 14 à 17 résidait dans la simple mise en œuvre du support Python. Si celui-ci fonctionnait, tant mieux. Malheureusement, ce n'était pas toujours le cas. La multitude de distributions Python et la diversité des environnements rendaient nos tests particulièrement difficiles.
Anaconda pouvait parfois fonctionner sous Windows, et les environnements virtuels Python aussi. Cependant, comme chaque utilisateur disposait d'une version différente de Python, un script ne pouvait même pas dépendre d'une version commune.
Modifier du code Python dans l'éditeur JSON était difficile et fastidieux. Ce langage délimite les blocs de code par des espaces, ce qui complique la tâche lorsqu'il faut coller ce code sous forme de chaîne de caractères dans JSL. De plus, les anciennes versions de JMP ne fournissaient pas suffisamment de rapports d'erreurs, rendant le débogage des scripts Python difficile.
Enfin, les transferts des tables de données et des matrices ont été effectués via le système de fichiers. Les tables de données ont été exportées au format CSV, ce qui s'avère lent avec des volumes de données importants. Le traitement des classes de grande taille fonctionne correctement, mais celui des données plus volumineuses est lent.
Notre objectif était de garantir une intégration Python optimale, sans aucune configuration. Pour ce faire, nous avons intégré Python 3.115 et JMP 18.0, installés directement avec JMP. L'environnement est ainsi commun : tous les utilisateurs disposent de la même version de Python et de la même version de JMP.
Nous sommes allés plus loin en veillant à ce que les transferts de données entre JSL et Python se fassent en mémoire, sans copie. Nous avons créé un environnement convivial et productif pour les développeurs Python. Nous proposons désormais un éditeur de scripts Python avec coloration syntaxique.
Vous pouvez exécuter des scripts Python purs directement depuis l'éditeur de scripts et, depuis l'environnement Python, accéder directement aux données JMP et au journal. Vous pouvez également appeler JSL et accéder aux données depuis Python. Nous avons considérablement amélioré la gestion des erreurs dans le journal JMP et le journal intégré.
Comme il s'agit désormais d'un environnement commun, nous pouvons le tester et le vérifier. Notre environnement est identique à celui que vous devriez voir. Nous avons ajouté une catégorie Python complète à l'index des scripts afin de… expliquer et de présenter des exemples des fonctionnalités désormais disponibles avec le package d'importation JMP et quelques autres packages utilitaires.
L'autre avantage est que cela nous permet d'étendre les fonctionnalités de JMP grâce à la vaste bibliothèque de packages Python. Nous ne cherchons pas à créer une alternative directe à JSL, mais plutôt à offrir un environnement familier et productif pour la programmation Python au sein de JMP.
Il s'agit d'une modernisation, d'une refonte complète. Certaines décisions de conception initiales concernant l'intégration Python de JMP étaient limitantes. Nous avons tout mis en œuvre pour minimiser les dysfonctionnements liés à ce changement, tout en assurant une base solide et stable pour l'avenir.
Tout porte à croire que les problèmes rencontrés se limiteront à la transition vers JMP. L'essentiel est que nous ne prenons désormais en charge que la version de Python fournie avec JMP. Il s'agit en quelque sorte d'un environnement virtuel JMP privé.
L'autre nouveauté dans les scripts concerne la gestion des tables de données par Python. Désormais, un objet JMP est créé à partir de cette table. Il s'agit d'un accès direct à la table de données JMP. Contrairement à la copie en mémoire, vous pouvez modifier la table existante. Ce n'est plus une simple copie.
JMP 14 à 17 créaient un objet DataFrame pandas en copiant les données via un fichier CSV temporaire. Pour les grands volumes de données, l'exportation au format CSV est très gourmande en ressources : le fichier devient volumineux et le traitement est lent. De plus, la conversion d'un format binaire en format texte, puis de texte en format binaire, peut entraîner une perte de précision.
Si vous avez absolument besoin de la même fonctionnalité, nous avons inclus dans les exemples un DT pour pandas Python qui fournit une fonction pandas. Son fonctionnement interne est identique à celui de la fonction précédente : elle crée un fichier CSV temporaire et indique à pandas d'importer ce fichier.
Il existe également un exemple JMP vers pandas montrant comment créer un DataFrame pandas en mémoire à partir d'un objet JMP Data Table qui construit une colonne dans pandas avec une colonne de JMP à la fois.
La fonction `SendMatrix` de Python, qui écrivait auparavant via le système de fichiers, créait un fichier de nombres à virgule flottante double précision (doubles) que NumPy devait lire. Désormais, cette opération s'effectue en interne, via la mémoire, et il s'agit d'une référence directe à la matrice plutôt que d'une copie.
La majeure partie de l'API Python de JSL reste intacte. Les modifications apportées ont principalement consisté à supprimer les arguments et fonctions obsolètes utilisés pour configurer la prise en charge Python d'origine afin de sélectionner une version de Python.
La seule API supprimée est la fonction Python `getgraphics`, qui récupérait une image depuis Matplotlib. Notre index de scripts contient un exemple montrant comment reproduire exactement ce que JMP faisait en interne, uniquement avec du JSL et du code Python. Allez, on y va ! Voyons voir. Finissons de la démo.
Voici JMP. Je souhaite vous montrer que vous verrez des icônes Python dans les barres d'outils et que, dans le menu Fichier > Nouveau, vous trouverez l'option « Script JSON », mais nous avons maintenant l'option « Nouveau script Python ». Nous allons ouvrir l'éditeur de script Python.
Nous pouvons afficher le journal intégré. Nous disposons d'un package d'importation JMP. Importez JMP. Nous avons veillé à inclure la documentation Python afin que vous puissiez exécuter la commande « help JMP Python ». Nous pouvons exécuter ce script. Vous constaterez que nous avons documenté les objets et les fonctions de ce package d'importation JMP principal.
Il y a un tas de constantes. La plupart des répertoires spéciaux sont représentés. Donc, on peut faire quelque chose. Et maintenant, je le fais depuis Python. JMP ouvert. JMP, bon, je ne peux pas taper aujourd'hui, JMP. SAMPLE DATA. Plus. Big Boss. Et comme en JSL, on peut sélectionner la ligne de code et l'exécuter dans le script. Et on a une grande classe.
Il ne s'agit pas d'une copie. Nous pouvons obtenir cet objet. Nous aurions pu utiliser `TT equals JMP open` pour obtenir une référence. Mais nous pouvons aussi utiliser `TT equals JMP.current`, ce qui nous donnera une référence à la table de données actuelle.
On peut faire des choses comme afficher TT. Cela nous indique que c'est une grande classe. Elle fait cinq colonnes sur quarante. Mais ce n'est pas tout. On peut faire encore plus amusant : TT. Nom. Et on peut utiliser les opérateurs de découpage de Python. Je lui demande d'afficher un nom sur deux dans la colonne « nom », en commençant par zéro.
En Python, l'indexation se fait comme il se doit, en commençant par zéro. L'index de notre tableau de données est colonne par ligne. Comme il s'agit d'un format en colonnes principales, si nous affichons un nom sur deux, nous obtenons : Katie, Jane, Lilly, James, Barbara, Susan, Joe et David.
Il s'agit d'un accès en direct, donc nous pouvons faire des choses comme… et nous pouvons faire des choses comme TT, et nous pouvons utiliser soit le nom, soit l'index de la colonne. Colonne, nous l'affichons. Cela nous donne, choisissez. Voici votre… J'en ai choisi un, n'est-ce pas, Lewis. Désolé. Zéro zéro. C'est Katie. Puisque le tableau de données est en direct. Vous pouvez faire Katie
Attendez. Minuscules. Majuscules et minuscules. Voici le résultat dans notre journal intégré. Vous remarquerez que nous l'avons modifié dans le tableau de données. Vous pouvez ainsi modifier les tableaux de données, y accéder en Python et même en créer. Nous avons fait de notre mieux.
Nous avons maintenant l'index des scripts. Je vais vous montrer… comme je l'ai dit, la fonction `getgraphics` est obsolète. Elle n'est plus valide dans JMP, mais l'exemple de l'index des scripts vous montre comment passer de l'ancienne méthode à la méthode interne utilisée dans JMP pour enregistrer la figure, ouvrir l'image et créer une nouvelle fenêtre avec cette image.
L'une des nouveautés intéressantes de l'environnement centré sur Python est la présence d'une catégorie dédiée. Le package d'importation JMP propose des objets de type table de données. Des exemples sont fournis pour chacun d'eux : on peut créer des colonnes, ajouter des lignes et enregistrer la table. On peut également accéder à ses propriétés, comme le nom des tables.
Celui-ci créerait une nouvelle table de données à l'aide de Python. Nous disposons également d'utilitaires JMP. Vous pouvez les utiliser pour exécuter JMP via pip, car ils créent leur propre environnement isolé. Lors de l'installation de paquets, ceux-ci doivent être placés dans cet environnement isolé.
Normalement, vous ne devriez rencontrer aucun problème de conflit entre les paquets JMP et d'autres installations Python. Nous avons veillé à ce que tout soit bien isolé. Ainsi, si nécessaire, la commande `create jpip` créera un script qui encapsulera le script pip de Python pour vous permettre l'installation. Vous pouvez également l'exécuter directement depuis la classe `JMP utils` de la gem.
Ici, nous allons afficher la commande `pip list`, qui s'exécutera directement depuis JMP. Cette commande renvoie la liste des paquets installés dans mon environnement Python. Voici un autre exemple d'installation de paquets.
Il y a quelques points à prendre en compte, d'où l'existence de la commande `create jpip`. Si un package comme NumPy est chargé en mémoire, Windows peut vous empêcher de le mettre à jour car il utilise une bibliothèque partagée. Certains packages nécessitent une compilation, qui peut alors devoir être effectuée en ligne de commande.
Certaines de ces méthodes peuvent fonctionner, mais elles nécessiteront peut-être une exécution en ligne de commande. C'est pourquoi il est conseillé de créer un script wrapper jpip. Une fois ce script exécuté, une fenêtre s'ouvrira et vous proposera un répertoire où enregistrer le fichier. Sélectionnez ensuite ce répertoire, et un script wrapper jpip exécutable en ligne de commande sera généré.
Lors de l'exécution, n'oubliez pas d'utiliser l'option `--minus` après l'installation. Cette option est automatiquement activée pour vous lorsque la commande est appelée depuis ce point. Une fonction JSL permet également d'effectuer l'installation. L'installation de paquets Python est encore plus simple : il suffit d'exécuter le script JSL, qui appellera pip en arrière-plan et configurera correctement toutes les variables d'environnement nécessaires à l'installation du paquet dans l'environnement isolé de JMP.
Allons-y. Nous pourrons ensuite vous montrer d'autres démonstrations. Il s'agit ici des fonctionnalités de base. Mais l'un des objectifs de ce processus était également de rendre JMP plus compatible avec Python et de faciliter l'extension de ses fonctionnalités grâce à des packages Python supplémentaires.
L'une des demandes les plus fréquentes de nos utilisateurs concerne l'importation de fichiers Parquet. Cette démonstration importe un tableau depuis mon disque dur, que j'ai téléchargé sur Internet. Exactement. Elle affiche ensuite la structure du fichier Parquet et construit un tableau de données JMP colonne par colonne à partir des données qu'il contient. Nous effacerons les journaux. Vous pourrez ainsi observer la démonstration.
Je n'ai pas exécuté le script. J'avais probablement sélectionné des éléments. Voilà. Il s'agissait d'un fichier Parquet. Nous avons utilisé Pyrow pour l'ouvrir, car Power Query l'a importé. Les propriétés du fichier Parquet indiquent qu'il contient mille lignes et qu'il est structuré en 13 colonnes et mille lignes. Le schéma affiche les noms des colonnes.
Tout en bas, nous pouvons montrer une autre chose : nous sommes loin d’avoir terminé les améliorations que nous souhaitons apporter côté Python, mais en attendant, vous pouvez exécuter JSL depuis Python.
Bien que le code Python ne prenne pas encore en charge des fonctionnalités telles que la définition de la largeur d'affichage ou la modification du type de colonne, vous pouvez créer une nouvelle colonne, mais pas en changer le type depuis Python. Ces fonctionnalités sont prévues pour l'instant, mais vous disposez d'une solution de contournement permettant d'exécuter des scripts JSL depuis Python, tout comme vous pouviez exécuter Python depuis JSL.
Grâce à cet environnement amélioré, vous pouvez désormais faire des allers-retours entre les deux. Python peut exécuter des scripts JSL. Les appels effectués dans Python peuvent ensuite être exécutés dans l'environnement JSL, ce qui permet d'imbriquer les appels pour réaliser des opérations qui seraient autrement impossibles. Par exemple, la prise en charge native des fichiers Parquet d'un type de données que JMP ne gère pas. Nous avons donc implémenté cette fonctionnalité en important un package Python.
Une autre chose qui me tient à cœur. Je ne suis pas vraiment statisticien, mais je m'intéresse à l'infographie et aux mathématiques en général. Ici, j'utilise OpenCL (Open Compute Language). Nous avons importé le package OpenCL pour créer une fractale de Mandelbrot. Commençons par vous montrer le rendu sur le processeur. L'exécution prendra environ 16 secondes.
C'est fastidieux, et vous remarquerez que JMP est lent. Il ne répond pas car Python a le contrôle à ce stade. Si vous placez une attente de cellule en cours au cœur de boucles serrées, vous pourrez reprendre le contrôle. Le processeur est utilisé pour générer cette fractale.
Maintenant, modifions le processus pour qu'il utilise le GPU, puis lançons le script. Et voilà ! La génération de l'image, son enregistrement et son ouverture dans un script ne prennent qu'une fraction de seconde. Voyons ce que ça donne. Avec le GPU, ça a pris 16 secondes… mais si on remonte assez loin, ça a pris 32 secondes pendant que je fais cette présentation, avec le CPU.
Cela ouvre la voie à l'utilisation du GPU avec JMP, désormais possible via Python. Nous avons testé PyOpenCL et PyCuda ; ainsi, si vous possédez une carte Nvidia et travaillez avec CUDA, vous pouvez utiliser PyCuda ou OpenCL, plus générique. Vous optimisez ainsi les capacités de calcul de JMP et exploitez pleinement la puissance de votre ordinateur.
Nous pouvons également nous connecter à SaaS via Python. SaaS possède un package SaaS, que nous avons installé… et une partie de ce travail a été réalisée par un de mes collègues. Effaçons les journaux. Nous voyons maintenant ce que j'ai et nous pouvons exécuter le script.
La collecte des données se déroule comme prévu. C'est parti. Ce script utilise JSL pour vérifier que tous les packages Python nécessaires à son exécution sont bien installés. Vous pouvez configurer cela. C'est en partie ce que vous voyez dans le journal : ces conditions sont déjà remplies. Voici tous les résultats obtenus lors de l'exécution du script en se connectant à SaaS. Le package Python de SaaS a été utilisé. Nous allons maintenant parcourir à nouveau le journal.
Le script est consigné dans le journal. Comme indiqué précédemment, nous disposons des informations de connexion au SaaS, de l'exécution des produits et de notre logistique. Le script renvoie ensuite les valeurs de sortie et la session SaaS se termine.
On a entendu dire que TensorFlow pourrait intéresser certaines personnes. Voici un exemple très simple. Eh bien non, j'ai installé TensorFlow et le code s'exécute depuis JSL, mais on aurait tout aussi bien pu l'exécuter directement depuis Python.
Il exécute TensorFlow et crée cette somme. Je suis sûr que vous trouverez des utilisations bien plus complexes que celles que je peux présenter ici. Py Digest en est un autre exemple. Voici un exemple que j'ai créé pour illustrer plusieurs fonctionnalités, notamment l'exécution de JSL qui me permet de sélectionner un répertoire à l'aide de la fonction `pickdirectory` de JMP, puis d'utiliser ce répertoire dans un script Python. Il s'agit d'un script Python pur. Il me permet de sélectionner un répertoire.
Ce programme calcule la somme de contrôle de chaque fichier du répertoire, l'enregistre dans une base de données SQLite, puis crée une table de données JMP à partir de cette base. Il vous initie ainsi à la programmation de bases de données, à la création d'une table de données JMP en Python et à l'exécution de JSL depuis Python.
Répertoire à sélectionner. J'ai beaucoup de données ici, alors choisissons le dossier de présentation, le dossier Parquet ou le dossier de sélection. Nous avons maintenant un tableau de sommes de contrôle. Ils ont créé le… il vérifie chaque fichier du répertoire, m'a donné leurs chemins d'accès et une somme de contrôle MD5 du contenu du fichier. Base de données construite. Table de données JMP construite à partir de Python, et utilisation de JSL pour définir la largeur des colonnes.
Là encore, nous n'avons pas encore implémenté cette fonctionnalité, mais nous l'envisageons. Vous pouvez toutefois effectuer des opérations JSL depuis votre code Python si vous le souhaitez.
Certaines personnes pourraient vouloir utiliser R. Dans ce cas précis, j'ai établi une connexion en utilisant notre serveur sur ma machine et dans notre environnement. Il était tout simplement plus facile d'exécuter notre serveur depuis un système Windows pour un environnement WSL Linux.
J'ai un serveur R qui tourne ici. J'utilise le client réservé. Je fais une petite opération : je crée un vecteur R sur le serveur, je calcule la somme des éléments et j'exécute ce script. Nous sommes connectés à notre serveur. Nous récupérons le vecteur et nous avons additionné tous ses éléments pour obtenir six. Voici quelques exemples : [insérer les exemples ici]. Si vous souhaitez quelque chose de très simple qui fonctionne en ligne de commande, il existe un exemple d'utilisation d'un processus pour exécuter du code R depuis la ligne de commande.
Enfin, la partie statistiques, pour laquelle Jon Saul a apporté son aide. Il s'agit de créer un exemple utilisant le package Python HDB scan. À noter concernant Matplotlib : sous Windows, Matplotlib ne dispose pas d'interface graphique. Par conséquent, pour visualiser les résultats, nous avons constaté que PyQt5 est la solution la plus performante.
Sur Mac, si vous utilisez Matplotlib comme moteur graphique, nous forcerons l'utilisation d'AGG, le moteur non graphique si vous n'avez pas installé PyQt5 ou PySide. En effet, Matplotlib sur Mac utilise automatiquement le moteur Cocoa, et un bug provoque l'arrêt de JMP lorsque vous fermez la dernière fenêtre Matplotlib.
Pour éviter ce problème lors de la configuration, si Matplotlib est détecté sur votre système et qu'un moteur graphique est installé, nous le chargerons et forcerons l'utilisation du moteur Qt. Sinon, nous nous assurons qu'il s'agit d'un moteur non graphique. Nous l'avons configuré comme moteur graphique. J'ai PyQt5 installé sur ma machine. Avec cet exemple, nous effectuons un clustering sur l'analyse HDB.
Affichons maintenant le journal intégré. Nous allons exécuter le script. Nous obtenons un graphique généré dans un tableau Matplotlib contenant les données. Ici, vous pouvez voir que nous avons ouvert JMP et utilisé la référence DT. Ce sont les échantillons dont je dispose. Croyez-moi.
Je vais reprendre la présentation. Nos priorités pour l'avenir proche : poursuivre l'amélioration et le perfectionnement, et accroître l'interopérabilité des données entre JMP et Python. Actuellement, la modification des colonnes est limitée : vous pouvez créer des colonnes de tout type, mais vous ne pouvez modifier et obtenir que les valeurs des colonnes numériques, de caractères, d'expressions ou d'états. La création de tables liées sera implémentée ultérieurement.
Bien que l'éditeur de scripts Python prenne en charge la coloration syntaxique, il ne gère pas encore l'indentation automatique. Nous allons nous pencher sur cette question.
L'objectif de la modernisation était de rendre l'intégration de Python à JMP fonctionnelle immédiatement. L'utilisation de JMP et Python devait être productive sans aucune configuration. Si cela n'avait pas fonctionné, le défi aurait été de taille. Pourquoi ne pas réduire le temps nécessaire aux développeurs Python pour être productifs au sein de JMP et améliorer les capacités de JMP ? Faire de JMP une plateforme analytique grâce à sa facilité d'extension via des packages Python externes.
Nous souhaitons améliorer notre capacité à charger différents formats de données développés par d'autres, comme le format Parquet (que nous avons également testé), ainsi que le format HDF5. Il existe une multitude de formats, bien plus qu'une seule équipe de développement ne pourrait tous les implémenter en interne. Grâce à cette méthode, vous pouvez intégrer le package Python et créer une table de données JMP à partir de ces données, tout en bénéficiant de la puissance de JMP.
Nous vous remercions pour votre temps. Nous espérons que vous avez apprécié notre travail et nous serions ravis de recevoir vos commentaires. Merci.