JMP 18 e la sua funzionalità Python incorporata forniscono accesso a molti strumenti open source, che aprono le porte all'interazione con numerose fonti di dati, tra cui SAS! Esploriamo come il pacchetto Python open source SASPy può essere sfruttato nell'ambiente JMP. In questo tutorial:
- Installa SASPy.
- Connettersi a SAS tramite uno script Python.
- Scarica e apri set di dati da SAS.
- Carica le tabelle su SAS.
- Eseguire il codice SAS.
Se sei interessato solo alla battuta finale, vedi i file allegati per gli script di esempio completi. Ma se vuoi rinfrescarti la memoria sull'uso di Python con JMP, ecco alcuni post di blog che possono aiutarti:
Introduzione all'integrazione Python in JMP® 18
Creazione di funzioni JSL implementate in Python
SASPy: Connessione di JMP con SAS
Gestito da SAS, SASPy open source consente di interfacciarsi con SAS tramite Python. SASPy supporta connessioni SAS Viya, nonché connessioni locali e remote tramite Integrated Object Model (IOM). Dopo una connessione, è possibile utilizzare la solida API per accedere a elenchi di librerie SAS; ottenere informazioni sulla libreria, elencare tabelle e informazioni sulle tabelle; ottenere informazioni sulle singole colonne; scaricare tabelle; convertire da e verso DataFrames panda; eseguire codice SAS; accedere al registro SAS; utilizzare procedure statistiche e di apprendimento automatico SAS; e... forse per ora è sufficiente.
Installazione di SASPy con JSL
Cominciamo da JSL-land. Per il tutorial, abbiamo bisogno di numpy, pandas e SASPy. Esegui il seguente script JSL per installare i pacchetti necessari.
Names Default To Here( 1 );
// install numpy and pandas packages
Python Install Packages( "numpy pandas saspy" );
Verifica che i pacchetti siano installati correttamente esaminando il log. Dovrai installarli solo una volta (supponendo che sia andato a buon fine) poiché i pacchetti installati persistono in JMP tra un riavvio e l'altro.
Connettersi a SAS tramite Python
Per connetterti, dovrai conoscere alcune informazioni sulla tua istanza SAS. Vale a dire che tipo di connessione utilizzerai (Viya vs. IOM), la posizione del server SAS e le credenziali necessarie per accedervi.
SASPy è altamente configurabile, quindi fai riferimento alla documentazione SASPy per il tuo specifico scenario di connessione. Trattiamo la connessione utilizzando due metodi:
- Attraverso, che si collega tramite http a un'istanza Viya, non necessita di installazione Java. Non funziona con SAS 9.4.
- IOM, che richiede Java installato sulla tua macchina. Può accedere a istanze locali su Windows o istanze remote su qualsiasi piattaforma.
Connettiti usando un dizionario
Inizia aprendo una finestra di script Python JMP. Apri anche il log incorporato facendo clic con il pulsante destro del mouse e selezionando "Open Log". Lo script seguente utilizza un dizionario Python contenente parametri di connessione. Sostituendo i parametri con quelli specifici della tua istanza SAS potrai connetterti. Sostituisci la variabile in SASSession con il dizionario corrispondente al tuo tipo di connessione, apri il log incorporato utilizzando il menu di scelta rapida e avvialo.
Nota sulla sicurezza: sebbene la tecnica di seguito possa aiutare a verificare/eseguire il debug della connessione SAS, salvare le credenziali in un file separato in cui è possibile controllare attentamente le autorizzazioni è probabilmente un'opzione migliore. Rivolgiti all'amministratore di sistema per ricevere supporto se non sei sicuro delle policy di sicurezza della tua organizzazione. Se i passaggi di seguito ti consentono di connetterti, vai avanti e fai il tifo, ma poi sposta le credenziali fuori dallo script utilizzando i passaggi nella sezione "Connessione tramite un file di configurazione".
Un'altra nota: possiamo eseguire Python da JSL e viceversa, quindi quando esegui il codice assicurati di controllare la presenza del logo Python blu e giallo nell'angolo per determinare se stai per eseguire Python o meno.
E un'ultima nota: JMP passa il controllo allo script Python durante l'esecuzione, quindi è normale che l'interfaccia utente grafica non risponda durante l'esecuzione del codice.
import saspy
viya = {
'url' : 'https://notrealsas.jmp.com:1234', # must contain http or https
'user': 'username',
'pw' : 'password',
'verify' : True, # verify certificates
}
iom = {
# location of java on your machine
'java': r'C:\Program Files (x86)\Common Files\Oracle\Java\javapath\javaw.exe',
}
iom_remote = {
'java': r'C:\Program Files (x86)\Common Files\Oracle\Java\javapath\javaw.exe',
'iomhost': 'notrealsas.jmp.com',
'iomport': 1234,
'omruser': 'username',
'omrpw': 'password',
}
# connect to SAS
# replace the second argument with your connection dict, mind the **
sas = saspy.SASsession(prompt=False, **viya)
print(sas)
Una connessione riuscita mostrerà qualcosa di simile a questo nel registro incorporato:
SAS Connection established. Subprocess id is 10040
Access Method = IOM
SAS Config name = default
SAS Config file = C:\Users\you\AppData\Roaming\JMP\JMP\Python\Python311\site-packages\saspy\sascfg.py
WORK Path = C:\Users\you\AppData\Local\Temp\SAS Temporary Files\_TD16996_SAS-PF4H167P_\Prc2\
SAS Version = 9.04.01M8P01182023
SASPy Version = 5.10.0
Teach me SAS = False
Batch = False
Results = Pandas
SAS Session Encoding = wlatin1
Python Encoding value = cp1252
SAS process Pid value = 16996
Se non riesci a connetterti, leggi attentamente il log per trovare indizi, verifica anche il tuo nome utente e la tua password (se applicabile). Aprendo il log incorporato prima di eseguire il tuo codice, verranno mostrate istruzioni di stampa e anche eventuali eccezioni. Altri motivi comuni per cui la connessione potrebbe fallire sono:
- Tramite
- L'indirizzo URL di SAS è inaccessibile o è scritto in modo errato.
- Impossibile formattare il parametro 'url' come http(s):// : , ad esempio, http : //server. jmp . com :5432
- Contrassegnare il campo "verify" come "true" quando l'istanza SAS utilizza certificati autofirmati (attenzione: la connessione con verify=false rappresenta un possibile rischio per la sicurezza).
- IOM
- Java non è installato (potrebbe essere necessario riavviare JMP o il computer dopo aver installato Java).
- Percorso non corretto per l'eseguibile Java. Prova a guardare il valore di ambiente per JAVA_HOME (Mac) o a cercare nel tuo percorso la cartella java (Windows).
Connettiti tramite un file di configurazione
Ora spostiamo le informazioni di connessione in un altro posto. Di nuovo, contatta l'amministratore di sistema per aderire alle pratiche di sicurezza nella tua organizzazione. Scarica il file di configurazione di esempio (sascfg_personal.py) allegato a questo post e sostituisci i valori con le tue credenziali. Prendi nota dei SAS_config_names in questo file per assicurarti che la tua opzione di connessione sia in quell'elenco. Quindi connettiti utilizzando la posizione del file:
import saspy
# replace with path to your config file
config_file = r'/some/path/to/your/config/sascfg_personal.py'
# replace the cfgname argument with the connection in your config file
sas = saspy.SASsession(prompt=False, cfgname='iom', cfgfile=config_file)
print(sas)
L'output dovrebbe essere lo stesso di quando ci si è collegati in precedenza.
Apertura di un set di dati
Aprire un set di dati scaricando un file
Un modo per importare set di dati SAS è scaricare direttamente il file. JMP è in grado di importare il tipo di file del set di dati (sas7bdat), che aiuta a preservare i formati e le etichette dei dati. Lo script Python mostrato di seguito scarica un file da SAS e usa JSL all'interno dello script Python per aprire il file.
import saspy
import jmp
import tempfile
config_file = r"C:\Users\user\Documents\sascfg_personal.py"
sas = saspy.SASsession(prompt=False, cfgname='iom', cfgfile=config_file)
print("Connected to SAS", sas)
table_name = 'cars'
library_name = 'sashelp'
print('Download ' + library_name + '.' + table_name)
data = sas.sasdata(table_name, library_name)
metadata = data.contents()
remote_file = metadata['Enginehost'].query('Label1 == "Filename"')['cValue1'].item()
# save in temp
tmp_dir = tempfile.gettempdir()
print('Copying ' + remote_file + ' to ' + tmp_dir + '...')
sas.download(tmp_dir, remote_file)
print('Opening table...')
jmp.run_jsl('''
dt1 = Open(
"%s/cars.sas7bdat",
Use Labels for Var Names( 1 )
);
''' % (tmp_dir) )
Dovresti vedere aperta una tabella dati contenente i dati del set di dati Cars.
Aprire un set di dati utilizzando un DataFrame pandas
SASpy consente di convertire set di dati da/verso un DataFrame pandas, il che può essere utile quando utilizzato come parte di una pipeline di dati per eseguire trasformazioni, pulizie, creazione di dati, ecc. Anche JMP stesso è in grado di importare DataFrame pandas come tabella JMP, il che aggiunge ancora più possibilità.
Nell'esempio Python seguente, apriamo il set di dati SASHELP.class come DataFrame, apriamo una tabella JMP e popoliamo la tabella JMP con i valori del DataFrame utilizzando la funzione di utilità definita dataFrameToJmpTable()
import saspy
import jmp
config_file = r"C:\Users\user\Documents\sascfg_personal.py"
sas = saspy.SASsession(prompt=False, cfgname='iom', cfgfile=config_file)
def dataFrameToJmpTable(dataFrame, table):
# Populate a jmp data table with a pandas dataframe
# Credit: Paul Nelson
cols = dataFrame.columns
values = dataFrame.values
for (i,k) in enumerate(cols):
print(i, k, dataFrame[k].dtype)
l = values[:,i].tolist() # turn pandas (numpy) column to a list
# create new columns based on the data type of the pandas column
value = values[0,:][i] # get example value from the i'th column
print("Example value: ", value)
if dataFrame[k].dtype == object and isinstance(value, str):
table.new_column(k, jmp.DataType.Character)
table[k] = l
elif dataFrame[k].dtype == 'float64': # numpy.number:
table.new_column(k, jmp.DataType.Numeric)
table[k] = l
elif dataFrame[k].dtype == 'int64': # or 'int32'
table.new_column(k, jmp.DataType.Numeric, dlen=4)
table[k] = l
else:
print('Unhandled column type: {dataFrame[k].dtype} . Defaulting to string.')
table.new_column(k, jmp.DataType.Character)
table[k] = l
sasData = sas.sasdata('Class', 'SASHELP',
results='pandas',
# dsopts={'where':'Age > 12',}
)
dataFrame = sasData.to_df()
values = dataFrame.values
num_rows = len(values)
dt = jmp.DataTable(name='Class', rows=num_rows)
dataFrameToJmpTable(dataFrame, dt)
Se l'operazione ha esito positivo, dovresti vedere la tabella dati della classe aperta.
Caricamento dei file su SAS
Similmente al download di set di dati, possiamo usare l'interfaccia DataFrame fornita da SASPy per caricare nuovamente i dati su SAS o caricare un file JMP. Ecco un esempio di caricamento di un file di tabella dati JMP su SAS e successiva importazione tramite la procedura SAS PROC IMPORT:
import saspy
import jmp
config_file = r"C:\Users\user\Documents\sascfg_personal.py"
sas = saspy.SASsession(prompt=False, cfgname='iom', cfgfile=config_file)
table_name = 'animals.jmp'
remote_file = sas.workpath + table_name
local_file = jmp.SAMPLE_DATA + table_name
results = sas.upload(local_file, remote_file, overwite=True)
print(results)
# import uploaded file as a data set, replace data set if existing
command = '''
PROC IMPORT OUT= WORK.animals
DATAFILE="{jmp_file}"
DBMS=JMP REPLACE;
RUN;
'''.format(jmp_file=remote_file)
results = sas.submit(command)
print(results)
Controlla il registro incorporato o scarica il file per verificare che abbia funzionato.
Di seguito è riportata una strategia di caricamento tramite DataFrame. Per prima cosa convertiamo la tabella JMP in un DataFrame, quindi la carichiamo tramite dataframe2sasdata() :
import saspy
import numpy as np
import pandas as pd
config_file = r"C:\Users\user\Documents\sascfg_personal.py"
sas = saspy.SASsession(prompt=False, cfgname='iom', cfgfile=config_file)
def jmpTableToDataFrame(dt) :
# Credit to Paul Nelson again
# Creating a Pandas dataframe from a JMP DataTable
df = pd.DataFrame()
for idx in range( len(dt) ):
if dt[idx].dtype == jmp.DataType.Numeric:
# creates numeric column directly using Python's Buffer Protocol
col = np.array( dt[idx] )
df[ dt[idx].name ] = col.tolist() # make it a list for pandas.
elif dt[idx].dtype == jmp.DataType.Character:
# create a list by iterating through values
col = list()
for i in range ( dt.nrows ):
col.append(dt[idx][i])
# Build character column from list
df[ dt[idx].name ] = col
else:
print("Not adding type:", dt[idx].dtype )
return df
data_table = jmp.open(jmp.SAMPLE_DATA + "Fitness.jmp")
df = jmpTableToDataFrame(data_table)
result = sas.dataframe2sasdata(df, 'Fitness', 'WORK')
print('WORK Tables:', sas.list_tables('WORK'))
Controllare il registro incorporato per verificare se la tabella Fitness viene visualizzata nell'elenco delle tabelle WORK.
Nella mia esperienza, usare file interi per la strategia di upload/download tende a essere la più veloce delle due strategie. Limita anche i problemi di conversione o rappresentazione dei dati. D'altro canto, i DataFrame sono ampiamente accettati da altri moduli Python. Consiglio di usare la strategia file a meno che non si abbia la necessità di fare ulteriore lavoro Python sui dati.
Esecuzione del codice SAS
Nell'ultima sezione abbiamo utilizzato la funzione sas.submit() per eseguire codice SAS per importare un file, ma possiamo farlo con qualsiasi codice SAS. Dai un'occhiata al file allegato saspy_cowboy_hat.jsl per un esempio che dimostra l'utilizzo di SASPy all'interno di uno script JSL e l'esecuzione di codice SAS per creare e visualizzare un grafico SAS classico. Crediti: @bryan_boone e @ChrisHemedinger .
Guardando avanti a JMP 19
Script, componenti aggiuntivi e pipeline che utilizzano SASpy in JMP 18 continueranno a essere supportati in JMP 19, il che significa che puoi continuare a utilizzare e sviluppare qualsiasi infrastruttura creata quando lavori con SAS. Inoltre, JMP 19 fornirà una serie di funzionalità correlate all'integrazione SAS, potenziando ulteriormente gli script e le tecniche menzionati in questo post. Alcune funzionalità familiari, come la finestra di dialogo di esportazione SAS e varie funzioni di integrazione JSL SAS, torneranno. Sono tutte basate sull'infrastruttura del connettore dati per consentire una facile configurazione, condivisione e utilizzo delle connessioni SAS in tutta l'organizzazione.
Hai JMP 18 al momento e vuoi provare le future funzionalità di integrazione SAS prima che JMP 19 entri in produzione? Un ottimo modo per fornire feedback e indicazioni mirati è candidarsi al programma JMP 19 Early Adopter (EA). Visita jmp.com/earlyadopter per maggiori informazioni.
Incorporando i robusti strumenti open source forniti da Python in JMP, diventano disponibili numerose opportunità per accedere e interagire con i dati. Lo script demo completo di SASPy può essere trovato allegato a questo post.
Inoltre, un grandissimo ringraziamento a Tom Weber per aver supportato SASPy. In quanto pacchetto open source, si prega di considerare di contribuire a miglioramenti o suggerimenti per SASPy su github .
Buona sceneggiatura a tutti!
Risorse
Configurazione SASPy
API Python SASPy
Esempio SASPy Quaderni Jupiter
Documentazione panda