JMP 18 et ses fonctionnalités Python intégrées donnent accès à de nombreux outils open source, ce qui ouvre la porte à l'interaction avec un certain nombre de sources de données, y compris SAS ! Explorons comment le package Python open source SASPy peut être exploité dans l'environnement JMP. Dans ce tutoriel, nous allons :
- Installez SASPy.
- Connectez-vous à SAS à l'aide d'un script Python.
- Téléchargez et ouvrez des ensembles de données depuis SAS.
- Télécharger des tables sur SAS.
- Exécuter le code SAS.
Si vous n'êtes intéressé que par la chute, consultez les fichiers joints pour des exemples de scripts complets. Mais si vous souhaitez un rappel sur l'utilisation de Python avec JMP, voici quelques articles de blog qui peuvent vous aider :
Premiers pas avec l'intégration Python dans JMP® 18
Création de fonctions JSL implémentées en Python
SASPy : connexion de JMP à SAS
Géré par SAS, le SASPy open source vous permet d'interagir avec SAS à l'aide de Python. SASPy prend en charge les connexions SAS Viya, ainsi que les connexions locales et distantes à l'aide du modèle d'objet intégré (IOM). Après une connexion, on peut utiliser l'API robuste pour accéder aux listes de bibliothèques SAS ; obtenir des informations sur les bibliothèques, répertorier les tables et les informations sur les tables ; obtenir des informations sur les colonnes individuelles ; télécharger des tables ; convertir vers et depuis des DataFrames pandas ; exécuter du code SAS ; accéder au journal SAS ; utiliser les procédures statistiques et d'apprentissage automatique SAS ; et... peut-être que c'est suffisant pour l'instant.
Installation de SASPy avec JSL
Commençons par le monde JSL. Pour le tutoriel, nous avons besoin de numpy, pandas et SASPy. Exécutez le script JSL suivant pour installer les packages nécessaires.
Names Default To Here( 1 );
// install numpy and pandas packages
Python Install Packages( "numpy pandas saspy" );
Vérifiez que les packages sont correctement installés en consultant le journal. Vous n'aurez besoin de les installer qu'une seule fois (en supposant que l'opération ait réussi) puisque les packages installés persistent dans JMP entre les redémarrages.
Se connecter à SAS à l'aide de Python
Pour vous connecter, vous devez connaître certaines informations sur votre instance SAS. À savoir le type de connexion que vous utiliserez (Viya ou IOM), l'emplacement du serveur SAS et les informations d'identification dont vous avez besoin pour y accéder.
SASPy est hautement configurable, donc reportez-vous à la documentation SASPy pour votre scénario de connexion spécifique. Nous abordons la connexion à l'aide de deux méthodes :
- Via, qui se connecte via http à une instance Viya, aucune installation Java n'est nécessaire. Ne fonctionne pas avec SAS 9.4.
- OIM, qui nécessite l'installation de Java sur votre machine. Peut accéder aux instances locales sur Windows ou aux instances distantes sur n'importe quelle plateforme.
Se connecter à l'aide d'un dictionnaire
Commencez par ouvrir une fenêtre de script JMP Python. Ouvrez également le journal intégré en cliquant avec le bouton droit de la souris et en sélectionnant « Ouvrir le journal ». Le script ci-dessous utilise un dictionnaire Python contenant des paramètres de connexion. Le remplacement des paramètres par ceux spécifiques à votre instance SAS vous permettra de vous connecter. Remplacez la variable dans SASSession par le dictionnaire correspondant à votre type de connexion, ouvrez le journal intégré à l'aide du menu contextuel et exécutez-le.
Remarque sur la sécurité : bien que la technique ci-dessous puisse vous aider à vérifier/déboguer votre connexion SAS, il est probablement préférable d'enregistrer vos informations d'identification dans un fichier séparé dans lequel vous pouvez contrôler étroitement les autorisations. Contactez votre administrateur système pour obtenir de l'aide si vous n'êtes pas sûr des politiques de sécurité de votre organisation. Si les étapes ci-dessous vous permettent de vous connecter, n'hésitez pas à vous réjouir, mais veuillez ensuite déplacer vos informations d'identification hors du script en suivant les étapes de la section « Connexion à l'aide d'un fichier de configuration ».
Autre remarque : nous pouvons exécuter Python à partir de JSL et vice versa, donc lors de l'exécution du code, assurez-vous de vérifier le coin pour la présence du logo Python bleu et jaune pour déterminer si vous êtes sur le point d'exécuter Python ou non.
Et une dernière remarque : JMP passe le contrôle au script Python pendant l'exécution, il est donc normal que l'interface graphique ne réponde pas pendant l'exécution du code.
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)
Une connexion réussie affichera quelque chose de similaire à ceci dans le journal intégré :
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
Si vous ne parvenez pas à vous connecter, lisez attentivement le journal pour trouver des indices, vérifiez également votre nom d'utilisateur et votre mot de passe (le cas échéant). L'ouverture du journal intégré avant d'exécuter votre code affichera les instructions d'impression ainsi que les éventuelles exceptions. D'autres raisons courantes pour lesquelles la connexion peut échouer sont les suivantes :
- Via
- L'adresse URL de SAS est inaccessible ou mal orthographiée.
- Impossible de formater le paramètre « url » en http(s):// : , par exemple, http : //server. jmp . com :5432
- Marquage du champ « vérifier » comme « vrai » lorsque l'instance SAS utilise des certificats auto-signés (avertissement : la connexion avec verify=false est un risque de sécurité possible).
- OIM
- Ne pas avoir Java installé (vous devrez peut-être redémarrer JMP ou votre ordinateur après l'installation de Java).
- Chemin d'accès incorrect vers l'exécutable Java. Essayez de consulter la valeur d'environnement pour JAVA_HOME (Mac) ou de rechercher votre chemin d'accès pour le dossier Java (Windows).
Se connecter à l'aide d'un fichier de configuration
Déplaçons maintenant les informations de connexion vers un autre emplacement. Encore une fois, contactez votre administrateur système pour qu'il respecte les pratiques de sécurité de votre organisation. Téléchargez l'exemple de fichier de configuration (sascfg_personal.py) joint à cet article et remplacez les valeurs par vos informations d'identification. Prenez note des SAS_config_names dans ce fichier pour vous assurer que votre option de connexion figure sur cette liste. Connectez-vous ensuite en utilisant l'emplacement du fichier :
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)
Le résultat doit être le même que lors de la connexion précédente.
Ouvrir un ensemble de données
Ouvrir un ensemble de données en téléchargeant un fichier
Une façon d'importer des ensembles de données SAS consiste à télécharger directement le fichier. JMP est capable d'importer le type de fichier d'ensemble de données (sas7bdat), ce qui permet de préserver les formats et les étiquettes des données. Le script Python ci-dessous télécharge un fichier depuis SAS et utilise JSL dans le script Python pour ouvrir le fichier.
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) )
Vous devriez voir une table de données ouverte contenant des données de l’ensemble de données Voitures.
Ouvrir un ensemble de données à l'aide d'un DataFrame pandas
SASpy permet de convertir des ensembles de données vers/depuis un DataFrame pandas, ce qui peut être utile lorsqu'il est utilisé dans le cadre d'un pipeline de données effectuant des transformations, du nettoyage, de la création de données, etc. JMP lui-même est également capable d'importer des DataFrames pandas sous forme de table JMP, ce qui ajoute encore plus de possibilités.
Dans l'exemple Python ci-dessous, nous ouvrons l'ensemble de données SASHELP.class en tant que DataFrame, ouvrons une table JMP et remplissons la table JMP avec les valeurs du DataFrame à l'aide de la fonction utilitaire définie 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)
Si vous réussissez, vous devriez voir le tableau de données de classe ouvert.
Téléchargement de fichiers sur SAS
De la même manière que pour le téléchargement d'ensembles de données, nous pouvons utiliser l'interface DataFrame fournie par SASPy pour télécharger des données vers SAS ou télécharger un fichier JMP. Voici un exemple de téléchargement d'un fichier de table de données JMP vers SAS, puis de son importation à l'aide de la procédure 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)
Vérifiez le journal intégré ou téléchargez le fichier pour vérifier que cela a fonctionné.
Vous trouverez ci-dessous une stratégie de téléchargement utilisant des DataFrames. Nous convertissons d'abord la table JMP en DataFrame, puis la téléchargeons à l'aide de 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'))
Vérifiez le journal intégré pour voir si la table Fitness apparaît dans la liste des tables WORK.
D'après mon expérience, l'utilisation de fichiers entiers pour la stratégie de téléchargement/téléchargement a tendance à être la plus rapide des deux stratégies. Cela limite également les problèmes de conversion ou de représentation des données. D'un autre côté, les DataFrames sont largement acceptés par d'autres modules Python. Je recommande d'utiliser la stratégie de fichier, sauf si vous avez besoin d'effectuer un travail Python supplémentaire sur les données.
Exécution du code SAS
Dans la section précédente, nous avons utilisé la fonction sas.submit() pour exécuter du code SAS afin d'importer un fichier, mais nous pouvons le faire avec n'importe quel code SAS. Consultez le fichier saspy_cowboy_hat.jsl ci-joint pour un exemple illustrant l'utilisation de SASPy dans un script JSL et l'exécution de code SAS pour créer et afficher un graphique SAS classique. Crédit : @bryan_boone et @ChrisHemedinger .
En prévision du JMP 19
Les scripts, les modules complémentaires et les pipelines utilisant SASpy dans JMP 18 continueront d'être pris en charge dans JMP 19, ce qui signifie que vous pouvez continuer à utiliser et à développer toute infrastructure créée lorsque vous travaillez avec SAS. De plus, JMP 19 fournira un certain nombre de fonctionnalités liées à l'intégration SAS, augmentant encore les scripts et les techniques mentionnés dans cet article. Certaines fonctionnalités familières, telles que la boîte de dialogue d'exportation SAS et diverses fonctions d'intégration JSL SAS, seront de retour. Elles sont toutes basées sur l'infrastructure du connecteur de données pour permettre une configuration, un partage et une utilisation faciles des connexions SAS dans toute votre organisation.
Vous possédez actuellement JMP 18 et souhaitez tester les futures fonctionnalités d'intégration SAS avant la mise en production de JMP 19 ? Une excellente façon de fournir des commentaires et des orientations ciblés est de postuler au programme Early Adopter (EA) de JMP 19. Visitez jmp.com/earlyadopter pour plus d'informations.
En intégrant les outils open source robustes fournis par Python dans JMP, de nombreuses possibilités d'accès et d'interaction avec les données deviennent disponibles. Le script de démonstration SASPy complet est disponible ci-joint à cet article.
Un grand merci également à Tom Weber pour son soutien à SASPy. En tant que package open source, n'hésitez pas à contribuer à des améliorations ou des suggestions pour SASPy sur github .
Bon script à tous !
Ressources
Configuration de SASPy
API Python SASPy
Exemple de notebooks Jupiter avec SASPy
Documentation sur les pandas