Questa presentazione illustra i nuovi e significativi aggiornamenti al supporto di Python in JMP 18, che offre un'integrazione molto più stretta con Python e un'esperienza utente decisamente più incentrata su Python. In JMP 18, potrai:
Queste funzionalità di JMP esposte a Python si espanderanno nel tempo, ma attualmente l'attenzione è focalizzata sulle funzionalità critiche e sul supporto dei dati in memoria. In questa presentazione, potrete ascoltare direttamente i cambiamenti e le motivazioni che li hanno guidati, nonché osservare le nuove funzionalità offerte agli utenti di JMP. Verranno discusse l'estensibilità e la capacità di importazione dei dati tramite l'utilizzo di pacchetti Python esterni e verrà mostrato l'accesso alle GPU tramite interfaccia Python utilizzando pacchetti esterni.
Ciao, sono Paul Nelson. Sono qui per parlare di JMP, Python e dei nostri prossimi passi. Dopo una delle presentazioni dello scorso anno, abbiamo deciso che potevamo migliorare. JMP e Python avevano margini di miglioramento, ed è proprio di questo che parlerò qui.
Le maggiori difficoltà riscontrate dai clienti con JMP dalla versione 14 alla 17 riguardavano semplicemente il funzionamento del supporto Python. Se funzionava, andava bene. Ma troppo spesso non era così. La presenza di numerose distribuzioni Python e ambienti diversi rendeva i test difficili per noi.
Anaconda a volte riusciva a funzionare su Windows, e a volte anche gli ambienti virtuali Python. Il problema era che, poiché ognuno aveva una versione di Python diversa, uno script non poteva nemmeno dipendere da una versione comune di Python nell'ambiente dell'utente.
Modificare il codice Python nell'editor JSON era difficile e spiacevole. In un linguaggio in cui i blocchi di codice sono delimitati da spazi, incollarli come stringa in JSL diventa complicato. Le vecchie versioni di JMP, inoltre, offrivano una segnalazione degli errori insufficiente, rendendo difficile il debug degli script Python.
Infine, il trasferimento delle tabelle e delle matrici di dati è avvenuto tramite il file system, e nel caso delle tabelle di dati è stato utilizzato un file CSV, che risulta lento se si hanno grandi quantità di dati. Con classi numerose funziona bene, ma con quantità di dati ancora maggiori la gestione diventa lenta.
La nostra visione è quella di garantire che l'integrazione con Python funzioni senza problemi, senza bisogno di alcuna configurazione. A tal fine, abbiamo integrato Python 3.115 e JMP 18.0, installandoli direttamente come parte di JMP. Si tratta di un ambiente comune, in cui tutti gli utenti avranno la stessa versione di Python e la stessa versione di JMP.
Abbiamo fatto un ulteriore passo avanti, assicurandoci che il flusso di dati tra JSL e Python avvenga tramite trasferimenti in memoria e accessi zero-copy alla memoria stessa. Abbiamo creato un ambiente accogliente e produttivo per i programmatori Python. Ora disponiamo anche di un editor di script Python con colorazione del codice ed evidenziazione della sintassi.
È possibile eseguire script Python puri direttamente dall'editor di script e, dall'interno dell'ambiente Python, è possibile accedere direttamente ai dati JMP, al log, richiamare JSL e accedere ai dati da Python. Abbiamo notevolmente migliorato la segnalazione degli errori nel log JMP e nel log incorporato.
Dato che ora si tratta di un ambiente comune, possiamo testarlo e verificarlo. Il nostro ambiente è identico a quello che dovreste vedere. Abbiamo aggiunto un'intera categoria Python nell'Indice di scripting per spiegare e mostrare esempi di ciò che è ora disponibile con l'importazione del pacchetto JMP e di un paio di altri pacchetti di utilità.
L'altro aspetto positivo è che questo ci offre la possibilità di estendere le funzionalità di JMP attraverso la vasta libreria di pacchetti Python. Non stiamo cercando di creare un'alternativa identica a JSL, bensì di fornire un ambiente familiare e produttivo per la programmazione Python all'interno di JMP.
Si tratta di modernizzazione, rinnovamento e revisione. Alcune delle scelte progettuali originali per l'integrazione di Python in JMP si sono rivelate limitanti. Abbiamo fatto tutto il possibile per ridurre al minimo i disagi causati dal cambiamento, fornendo al contempo una base solida e stabile per il futuro.
Ci si aspetta che i problemi siano limitati a questa transizione a JMP. L'aspetto fondamentale è che ora supportiamo solo la versione di Python che distribuiamo con JMP. Pensatela come un ambiente virtuale JMP privato.
Un'altra novità che riguarda gli script è il modo in cui Python invia le tabelle dati. Ora crea un oggetto JMP che rappresenta la tabella dati. Questo consente l'accesso in tempo reale alla tabella dati JMP. La copia in memoria permette di modificare la tabella esistente, non è più una semplice copia.
Nelle versioni di JMP dalla 14 alla 17, veniva creato un oggetto DataFrame di pandas copiando i dati in un file CSV temporaneo presente nel file system. Per grandi quantità di dati, l'esportazione in CSV diventa estremamente lenta e di grandi dimensioni. Inoltre, si corre il rischio di una potenziale perdita di precisione, poiché si passa da un formato binario a un formato testuale e viceversa.
Se hai davvero bisogno della stessa funzionalità, nei file di esempio abbiamo fornito un DT per pandas Python che offre una funzione a due pandas. Questa funziona come faceva internamente in precedenza: crea un file CSV temporaneo e indica a pandas di importarlo.
È disponibile anche un esempio di conversione da JMP a pandas che mostra come creare un DataFrame pandas in memoria a partire da un oggetto JMP Data Table, il quale a sua volta costruisce una colonna in pandas utilizzando una colonna proveniente dalla colonna JMP.
Anche la funzione Python Send Matrix in passato scriveva tramite il file system. Scriveva un file di valori double affinché NumPy potesse leggerlo. Ora questo processo avviene internamente in memoria, con un riferimento diretto alla matrice anziché una copia.
La maggior parte dell'API Python di JSL rimane intatta. Le modifiche apportate hanno riguardato principalmente la rimozione di argomenti e funzioni obsoleti utilizzati per configurare il supporto Python originale in modo che selezionasse una versione di Python.
L'unica API rimossa è stata la funzione Python get graphics, che recuperava un'immagine da Matplotlib, e nel nostro indice di scripting abbiamo un esempio che mostra esattamente come fare la stessa cosa che JMP faceva internamente usando solo JSL e codice Python. Mostracelo. Vediamo. Usciamo dalla demo.
Qui abbiamo JMP. Una delle cose che voglio mostrarvi è che vedrete le icone di Python nelle barre degli strumenti e nel menu File > Nuovo abbiamo Script JSON, ma ora abbiamo un nuovo script Python. Apriamo l'editor di script Python.
Possiamo usare il comando show embedded log. Abbiamo un pacchetto di importazione JMP. Importiamo JMP. Ci siamo impegnati per assicurarci di aver inserito le stringhe di documentazione Python in modo che tu possa eseguire help JMP Python. Possiamo eseguire quello script. Vedrai che abbiamo documentato gli oggetti e le funzioni all'interno di questo pacchetto di importazione JMP di livello superiore.
Ci sono un sacco di costanti. Sono rappresentate quasi tutte le directory speciali. Quindi possiamo farlo. E ora lo faccio da Python. JMP aperto. JMP, beh, oggi non riesco a digitare, JMP. DATI DI ESEMPIO. Inoltre. Big Boss. E proprio come in JSL, possiamo selezionare la riga di codice ed eseguirla nello script e... E abbiamo una grande classe.
Ora, questa non è una copia. Possiamo ottenere quell'oggetto. Avremmo potuto impostare TT uguale a JMP aperto e avremmo avuto un riferimento. Ma possiamo anche impostare TT uguale a JMP.current. Questo ci darà un riferimento alla tabella dati corrente.
Beh, possiamo fare cose come stampare TT. Questo ci dice che è una classe grande. Ha cinque colonne per 40. Ma c'è di più. Si può fare di più divertente. TT. Nome. E possiamo usare gli operatori di slicing di Python. Gli sto dicendo di darci un nome sì e uno no nella colonna del nome a partire da zero.
In Python, l'indicizzazione avviene a partire da zero. L'indice della nostra tabella dati è colonna per riga. Poiché il formato è di tipo column-main, se stampiamo "Ogni altro nome", otteniamo Katie, Jane, Lilly, James, Barbara, Susan, Joe e David.
Questo è un accesso live, quindi possiamo fare cose come... e possiamo fare cose come TT, e possiamo usare il nome o l'indice di colonna. Colonna che stampiamo. Questo ci dà, scegli. Ecco il tuo... Ne ho scelto uno, giusto, Lewis. Scusa. Zero zero. È Katie. Dato che la tabella dati è live. Puoi fare Katie
Aspetta. Minuscolo. Maiuscole e minuscole. Ora vediamo l'output nel nostro log incorporato. Noterai. L'abbiamo modificato nella tabella dati. Questo ti dà la possibilità di modificare le tabelle dati, accedere alle tabelle dati in modo Python e puoi creare tabelle dati da Python. Ci siamo impegnati.
Ora abbiamo l'indice degli script. Vi mostrerò... qui, come ho detto, la funzione get graphics è deprecata. In realtà non è più una funzione valida in JMP, ma l'esempio nell'indice degli script mostra come passare da quello che avevate prima a come lo facevamo internamente in JMP per salvare la figura, aprire l'immagine e creare una nuova finestra con l'immagine.
Una delle nuove e interessanti funzionalità dell'ambiente incentrato su Python è la categoria Python, che è una categoria a sé stante. Il pacchetto di importazione JMP ha oggetti tabella dati. Ci sono esempi per ognuno di essi: possiamo creare nuove colonne, aggiungere righe e salvare la tabella. Le proprietà su di essa, come ottenere i nomi delle tabelle. Tutto questo.
Questo creerebbe una nuova tabella dati basata su Python. Abbiamo anche le utilità JMP. In questo modo, possiamo utilizzare pip JMP per eseguire il tutto, poiché crea un ambiente isolato. Quando installiamo i pacchetti, questi devono trovarsi nell'ambiente isolato di JMP.
Speriamo che non riscontriate problemi con i pacchetti che avete in JMP che entrano in conflitto con altri elementi o altre installazioni di Python. Li abbiamo mantenuti isolati. Quindi, in questo caso, se necessario... abbiamo creato jpip che creerà uno script che avvolgerà lo script pip di Python per consentirvi di installarlo, oppure potete eseguirlo dalla classe JMP utils all'interno della gemma.
Qui mostreremo l'elenco dei comandi pip e questo verrà eseguito. Chiama pip e restituisce l'elenco dei pacchetti che ho installato nel mio ambiente Python. Un altro esempio qui puoi effettivamente installare pacchetti. E questo verrà eseguito direttamente all'interno di JMP.
Ci sono un paio di avvertenze, ed è per questo che esiste il comando create jpip. Se un pacchetto viene caricato in memoria, come NumPy, poiché ha una libreria condivisa, Windows potrebbe impedirti di aggiornare quel pacchetto. Ci sono alcuni pacchetti che richiedono la compilazione. Questi potrebbero dover essere compilati dalla riga di comando.
Alcuni di questi potrebbero funzionare, ma potrebbero richiedere l'esecuzione da riga di comando. Ecco perché è consigliabile creare uno script wrapper jpip. Quando viene eseguito, si aprirà una finestra che indica la directory in cui scrivere il file; selezionando la cartella, verrà generato uno script wrapper jpip eseguibile da riga di comando.
Quando lo esegui, devi usare il flag utente minus minus dopo l'installazione. Lo facciamo automaticamente per te quando viene chiamato da qui. C'è anche una funzione JSL che eseguirà l'installazione. Installare pacchetti Python è ancora più semplice. Puoi semplicemente eseguire lo script JSL e questo chiamerà pip in background, impostando correttamente tutte le variabili d'ambiente necessarie per inserire il pacchetto nell'ambiente isolato di JMP.
Andiamo. Poi possiamo mostrarvi altre demo. Queste sono le cose semplici e basilari. Ma quello che abbiamo fatto... parte di tutto questo processo è stato rendere JMP più compatibile con Python e molto più facile estendere le sue funzionalità tramite pacchetti Python aggiuntivi.
Una delle richieste di supporto più frequenti che riceviamo è la possibilità di importare file Parquet. Questa demo prende una tabella dal mio disco rigido. Una che ho scaricato da Internet. Esatto. Poi stampa la struttura del file Parquet e crea una tabella dati JMP colonna per colonna a partire dai dati presenti nel file Parquet. Cancelleremo i log. Guardate come si fa.
Non ho eseguito lo script. Probabilmente avevo evidenziato alcune cose. Ecco. Questo era un file parquet. Abbiamo creato il file parquet pyrrow come importato da PQ. Le proprietà del file Parquet. Sono mille righe. La forma è di 13 colonne per mille righe. Lo schema mostra il pattern con i nomi delle colonne.
Qui in fondo possiamo mostrare un'altra cosa: siamo ben lungi dall'aver finito con le cose che vogliamo migliorare sul lato Python, ma fino a quando non ci arriveremo, è possibile eseguire JSL da Python.
Anche se il codice Python non supporta ancora funzionalità come l'impostazione della larghezza di visualizzazione o la modifica dei tipi di colonna, è possibile creare una nuova colonna, ma non è possibile modificarne il tipo da Python. Questi sono aspetti che vorremmo implementare in futuro, ma al momento esiste una soluzione alternativa per eseguire script JSL da Python, proprio come era possibile eseguire codice Python da JSL.
Ora, grazie a questo ambiente migliorato, è possibile interagire tra i due. Python può eseguire script JSL, che a loro volta possono essere eseguiti nell'ambiente JSL, consentendo di annidare le chiamate per ottenere risultati altrimenti impossibili. Ad esempio, è possibile gestire un file Parquet con un tipo di dati che JMP non supporta nativamente. Tuttavia, abbiamo risolto questo problema importando un pacchetto Python apposito.
Un'altra cosa che mi sta a cuore. Non sono un grande statistico, ma me la cavo con la grafica e la matematica in generale. Ecco come usare Open Compute Language o OpenCL. Abbiamo importato il pacchetto OpenCL. Per creare un frattale di Mandelbrot. Prima di tutto, vediamo come funziona con la CPU. Lo facciamo con la CPU. L'esecuzione richiederà circa 16 secondi.
Questo è un processo doloroso e noterete che JMP stesso è lento. Non risponde perché a questo punto il controllo è in mano a Python. Se inserite un'attesa di cella in esecuzione all'interno di cicli stretti, sarete in grado di riprendere il controllo. Questo è il modo in cui viene utilizzata la CPU per generare questo frattale.
Ora modifichiamolo in modo che utilizzi la GPU e avviamo lo script. Boom. Ci vuole una frazione di secondo per generare l'immagine, salvarla e aprirla in uno script e vediamo cosa ne pensiamo. Ci sono voluti 16 secondi usando le GPU contro... ma se torniamo indietro nel tempo, in realtà ci sono voluti 32 secondi mentre sono qui a presentare per farlo sulla CPU.
Questo apre la strada all'utilizzo della GPU con JMP, ora possibile tramite Python. Abbiamo testato sia PyOpenCL che PyCuda, quindi se si possiede una scheda Nvidia e si lavora con CUDA, è possibile utilizzare PyCuda o il più generico OpenCL. Questo potenzia ulteriormente le capacità di calcolo di JMP, senza lasciare inutilizzata la potenza del computer.
Possiamo anche connetterci a SaaS tramite Python. SaaS ha un pacchetto SaaS y, e lo abbiamo installato in... e questo è parte del lavoro che uno dei miei colleghi ha messo insieme. Cancelliamo i log. Vediamo cosa ho effettivamente e possiamo eseguire lo script.
Sta raccogliendo queste informazioni come dovrebbe. Ecco fatto. Questo script utilizza JSL per verificare che tutti i pacchetti Python necessari per l'esecuzione siano già installati, e puoi configurarlo. Questo è ciò che vedi qui nel log, ovvero che questi requisiti sono già soddisfatti. Ecco tutti i risultati ottenuti eseguendo lo script e connettendosi a SaaS. Utilizzando il pacchetto SaaS Py, rivedremo il log.
Lo script viene visualizzato nel log. Come ho detto qui. Abbiamo le informazioni di connessione dove si connette al SaaS, esegue i prodotti. La nostra logistica. Quindi restituisce i valori di output e la fine della sessione SaaS.
Abbiamo sentito dire che TensorFlow potrebbe essere una tecnologia di interesse. Ecco un esempio molto semplice. Sbagliato, di nuovo ho installato TensorFlow e questo codice è in esecuzione da JSL, ma avremmo potuto facilmente eseguirlo direttamente da Python.
Esegue il flusso tensoriale che crea questa somma. Sono sicuro che troverai usi molto più complicati di quelli che ho da mostrare. Py digest è un altro. È, screen. Ecco un esempio che ho creato per mostrare, uno era per mostrare diverse cose, incluso l'esecuzione di JSL dove mi permette di usare per selezionare una directory usando JMPs pick directory, JSL pick directory e usarlo in uno script python. Questo è tutto puro script python. Mi permette di selezionare una directory.
Crea un checksum per ogni file nella directory. Inserisce questo checksum in un database SQLite e quindi crea una tabella dati JMP a partire dal database. Ti offre un'introduzione alla programmazione di database, alla creazione di una tabella dati JMP da Python e all'esecuzione di JSL da Python.
Directory da selezionare. Ho molti dati qui, quindi scegliamo semplicemente la presentazione, la cartella parquet o selezioniamo la cartella. Ora abbiamo una tabella di checksum. Hanno creato... controlla ogni file nella directory, mi ha dato i loro nomi di percorso e un checksum MD5 del contenuto del file. Ha creato il database. Ha creato la tabella dati JMP da Python e ha anche usato JSL per impostare la larghezza delle colonne.
Anche in questo caso, non abbiamo ancora implementato questa funzionalità, ma è nella lista delle cose da valutare. Tuttavia, è possibile eseguire operazioni JSL dal proprio codice Python, se lo si desidera.
Alcune persone potrebbero voler usare R. Bene, in questo caso, ho creato una connessione usando il nostro server sulla mia macchina e nel nostro ambiente. Era semplicemente più facile eseguire il nostro server da un sistema Windows per l'ambiente Linux WSL.
Ho un demone R serve in esecuzione qui. E sto usando il client riservato. Sto facendo solo una piccola cosa, creando un vettore R sul server, sommando il risultato ed eseguendo questo script. Ci siamo connessi al nostro server. Otteniamo il vettore e abbiamo sommato tutti gli elementi per ottenere sei. Il nostro py2. Ci sono anche alcuni esempi che abbiamo. Se vuoi qualcosa di veramente semplice che funzioni dalla riga di comando, c'è un esempio su come usare un processo per eseguire R dalla riga di comando.
Infine, quello di statistica in cui Jon Saul lo ha aiutato. Crea un esempio che utilizza il pacchetto Python HDB scan. Una cosa da notare riguardo a Matplotlib. Matplotlib su Windows non ha un backend grafico, quindi se vuoi vedere un output, abbiamo scoperto che PyQt5 funziona meglio.
Come back-end e. Su Mac, se usi Matplotlib, forzeremo l'utilizzo di AGG, il back-end non grafico, se non hai installato PyQt5 o PySide. Perché Matplotlib su Mac utilizza automaticamente il back-end Cocoa, e c'è un bug per cui quando chiudi l'ultima finestra di Matplotlib su Mac, JMP si chiude.
Per proteggerci da ciò, dove forziamo, se troviamo Matplotlib sul tuo sistema, se c'è un back-end, caricheremo Matplotlib e lo forzeremo a usare il back-end Qt. Altrimenti, ci assicuriamo che sia un back-end non grafico. Lo abbiamo impostato come back-end. Ho PyQt5 sulla mia macchina. Con questo esempio eseguiamo alcuni clustering sulla scansione HDB.
Ora mostriamo il log incorporato. Eseguiremo lo script. Quello che otteniamo è una figura generata in una tabella di dati di Matplotlib. Qui potete vedere che abbiamo aperto JMP e preso il riferimento DT. Questi sono i campioni che ho. Credetemi.
Riprenderò la presentazione. Le nostre priorità per il prossimo futuro: perfezionamento e miglioramento continui. Aumentare l'interoperabilità dei dati tra JMP e Python. Al momento, la limitazione nella modifica delle colonne è che è possibile creare colonne di qualsiasi tipo, ma è possibile modificare e ottenere valori solo per colonne numeriche e alfanumeriche, colonne di espressione o colonne di stato. La creazione di tabelle collegate verrà implementata in futuro.
Sebbene l'editor di script Python supporti la colorazione del codice e l'evidenziazione della sintassi, non offre ancora il supporto per l'indentazione automatica. Stiamo valutando anche questa opzione.
L'obiettivo della modernizzazione era quello di rendere l'integrazione di JMP con Python immediatamente funzionante. Si sarebbe dovuto poter essere produttivi con JMP e Python senza alcuna configurazione. In caso contrario, sarebbe stato molto problematico. Perché non ridurre il tempo necessario ai programmatori Python per essere produttivi all'interno di JMP e migliorare le capacità di JMP? Renderlo un hub analitico grazie alla facile espansione di JMP tramite pacchetti Python esterni.
Migliorare la nostra capacità di caricare diversi formati di dati che altri hanno sviluppato dedicando tempo alla loro creazione, come il formato Parquet, che abbiamo testato anche con HDF5. Esistono moltissimi formati, più di quanti un singolo team di sviluppo possa gestire internamente, ma con questo metodo è possibile utilizzare il pacchetto Python e creare una tabella dati JMP a partire da quei dati, sfruttandone appieno le potenzialità all'interno di JMP.
Grazie per il tempo che ci avete dedicato. Speriamo che abbiate apprezzato il nostro lavoro e saremmo lieti di ricevere un vostro feedback. Grazie.