JMP 18 und seine eingebettete Python-Funktionalität bieten Zugriff auf viele Open-Source-Tools, was die Interaktion mit einer Reihe von Datenquellen, einschließlich SAS, ermöglicht! Sehen wir uns an, wie das Open-Source-Python-Paket SASPy in der JMP-Umgebung genutzt werden kann. In diesem Tutorial:
- Installieren Sie SASPy.
- Stellen Sie mithilfe eines Python-Skripts eine Verbindung zu SAS her.
- Laden Sie Datensätze von SAS herunter und öffnen Sie sie.
- Laden Sie Tabellen zu SAS hoch.
- SAS-Code ausführen.
Wenn Sie nur an der Pointe interessiert sind, finden Sie in den angehängten Dateien vollständige Beispielskripte. Wenn Sie jedoch Ihre Kenntnisse zur Verwendung von Python mit JMP auffrischen möchten, können Ihnen die folgenden Blogbeiträge weiterhelfen:
Erste Schritte mit der Python-Integration in JMP® 18
Erstellen von in Python implementierten JSL-Funktionen
SASPy: JMP mit SAS verbinden
Das von SAS verwaltete Open-Source- Programm SASPy ermöglicht Ihnen die Schnittstelle zu SAS über Python. SASPy unterstützt SAS Viya-Verbindungen sowie lokale und Remote-Verbindungen über das Integrated Object Model (IOM). Nach dem Herstellen einer Verbindung können Sie über die robuste API auf Listen von SAS-Bibliotheken zugreifen, Bibliotheksinformationen, Listentabellen und Tabelleninformationen abrufen, Informationen zu einzelnen Spalten abrufen, Tabellen herunterladen, in und aus Pandas DataFrames konvertieren, SAS-Code ausführen, auf das SAS-Protokoll zugreifen, statistische und maschinelle Lernverfahren von SAS nutzen und … vielleicht ist das fürs Erste genug.
Installieren von SASPy mit JSL
Beginnen wir im JSL-Land. Für das Tutorial benötigen wir Numpy, Pandas und SASPy. Führen Sie das folgende JSL-Skript aus, um die benötigten Pakete zu installieren.
Names Default To Here( 1 );
// install numpy and pandas packages
Python Install Packages( "numpy pandas saspy" );
Überprüfen Sie anhand des Protokolls, ob die Pakete korrekt installiert wurden. Sie müssen sie nur einmal installieren (vorausgesetzt, es war erfolgreich), da die installierten Pakete zwischen Neustarts in JMP bestehen bleiben.
Herstellen einer Verbindung mit SAS mithilfe von Python
Zum Herstellen einer Verbindung benötigen Sie einige Informationen zu Ihrer SAS-Instanz. Nämlich, welchen Verbindungstyp Sie verwenden (Viya oder IOM), den Standort des SAS-Servers und alle Anmeldeinformationen, die Sie für den Zugriff benötigen.
SASPy ist in hohem Maße konfigurierbar. Lesen Sie daher die SASPy-Dokumentation für Ihr spezifisches Verbindungsszenario. Wir behandeln die Verbindung mit zwei Methoden:
- Über, das über http eine Verbindung zu einer Viya-Instanz herstellt, keine Java-Installation erforderlich. Funktioniert nicht mit SAS 9.4.
- IOM, das Java auf Ihrem Computer installiert haben muss. Kann auf lokale Instanzen unter Windows oder Remote-Instanzen auf jeder Plattform zugreifen.
Herstellen einer Verbindung mithilfe eines Wörterbuchs
Öffnen Sie zunächst ein JMP-Python-Skriptfenster. Öffnen Sie auch das eingebettete Protokoll, indem Sie mit der rechten Maustaste klicken und „Protokoll öffnen“ auswählen. Das folgende Skript verwendet ein Python-Wörterbuch mit Verbindungsparametern. Wenn Sie die Parameter durch solche ersetzen, die für Ihre SAS-Instanz spezifisch sind, können Sie eine Verbindung herstellen. Ersetzen Sie die Variable in SASSession durch das Wörterbuch, das Ihrem Verbindungstyp entspricht, öffnen Sie das eingebettete Protokoll über das Rechtsklickmenü und führen Sie es aus.
Hinweis zur Sicherheit: Die folgende Technik kann zwar dabei helfen, Ihre SAS-Verbindung zu überprüfen/debuggen, aber das Speichern Ihrer Anmeldeinformationen in einer separaten Datei, in der Sie die Berechtigungen streng kontrollieren können, ist wahrscheinlich eine bessere Option. Wenden Sie sich an Ihren Systemadministrator, wenn Sie sich über die Sicherheitsrichtlinien Ihres Unternehmens nicht sicher sind. Wenn Sie mit den folgenden Schritten eine Verbindung herstellen können, können Sie weitermachen und jubeln, aber verschieben Sie dann Ihre Anmeldeinformationen mithilfe der Schritte im Abschnitt „Verbindung mithilfe einer Konfigurationsdatei herstellen“ aus dem Skript.
Noch ein Hinweis: Wir können Python von JSL aus ausführen und umgekehrt. Achten Sie daher beim Ausführen von Code darauf, dass in der Ecke das blau-gelbe Python-Logo angezeigt wird, um festzustellen, ob Sie Python ausführen oder nicht.
Und noch ein letzter Hinweis: JMP übergibt während der Ausführung die Kontrolle an das Python-Skript, daher kommt es normalerweise vor, dass die GUI während der Ausführung des Codes nicht reagiert.
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)
Bei einer erfolgreichen Verbindung wird im eingebetteten Protokoll etwa Folgendes angezeigt:
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
Wenn Sie keine Verbindung herstellen können, lesen Sie das Protokoll sorgfältig durch, um Hinweise zu erhalten. Überprüfen Sie außerdem Ihren Benutzernamen und Ihr Passwort (falls zutreffend). Wenn Sie das eingebettete Protokoll öffnen, bevor Sie Ihren Code ausführen, werden Druckanweisungen sowie etwaige Ausnahmen angezeigt. Weitere häufige Gründe, warum die Verbindung fehlschlagen kann, sind:
- Über
- Die URL-Adresse von SAS ist nicht zugänglich oder falsch geschrieben.
- Der Parameter „URL“ kann nicht als http(s):// formatiert werden. : , zum Beispiel http : //server. jmp . com :5432
- Markieren Sie das Feld „Verify“ als „true“, wenn die SAS-Instanz selbstsignierte Zertifikate verwendet (Warnung: Eine Verbindung mit „verify=false“ stellt ein mögliches Sicherheitsrisiko dar).
- IOM
- Java ist nicht installiert (möglicherweise müssen Sie JMP oder Ihren Computer nach der Installation von Java neu starten).
- Falscher Pfad zur ausführbaren Java-Datei. Sehen Sie sich den Umgebungswert für JAVA_HOME (Mac) an oder suchen Sie in Ihrem Pfad nach dem Java-Ordner (Windows).
Herstellen einer Verbindung mithilfe einer Konfigurationsdatei
Verschieben wir nun die Verbindungsinformationen an einen anderen Ort. Wenden Sie sich erneut an Ihren Systemadministrator, um die Sicherheitspraktiken in Ihrer Organisation einzuhalten. Laden Sie die diesem Beitrag beigefügte Beispielkonfigurationsdatei (sascfg_personal.py) herunter und ersetzen Sie die Werte durch Ihre Anmeldeinformationen. Notieren Sie sich die SAS_config_names in dieser Datei, um sicherzustellen, dass Ihre Verbindungsoption auf dieser Liste steht. Stellen Sie dann eine Verbindung über den Dateispeicherort her:
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)
Die Ausgabe sollte genauso aussehen wie bei der vorherigen Verbindung.
Öffnen eines Datensatzes
Öffnen eines Datensatzes durch Herunterladen einer Datei
Eine Möglichkeit, SAS-Datensätze zu importieren, besteht darin, die Datei direkt herunterzuladen. JMP kann den Datensatzdateityp (sas7bdat) importieren, wodurch Datenformate und Beschriftungen erhalten bleiben. Das unten gezeigte Python-Skript lädt eine Datei von SAS herunter und verwendet JSL innerhalb des Python-Skripts, um die Datei zu öffnen.
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) )
Sie sollten eine geöffnete Datentabelle mit Daten aus dem Datensatz „Cars“ sehen.
Öffnen Sie einen Datensatz mit einem Pandas DataFrame
SASpy ermöglicht die Konvertierung von Datensätzen in/aus einem Pandas-DataFrame, was nützlich sein kann, wenn es als Teil einer Datenpipeline verwendet wird, die Transformationen, Bereinigungen, Datenerstellung usw. durchführt. JMP selbst kann auch Pandas-DataFrames als JMP-Tabelle importieren, was noch mehr Möglichkeiten bietet.
Im folgenden Python-Beispiel öffnen wir den Datensatz SASHELP.class als DataFrame, öffnen eine JMP-Tabelle und füllen die JMP-Tabelle mit den Werten aus dem DataFrame mithilfe der definierten Hilfsfunktion 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)
Wenn dies erfolgreich war, sollte die geöffnete Klassendatentabelle angezeigt werden.
Hochladen von Dateien zu SAS
Ähnlich wie beim Herunterladen von Datensätzen können wir die von SASPy bereitgestellte DataFrame-Schnittstelle verwenden, um Daten zurück zu SAS hochzuladen oder eine JMP-Datei hochzuladen. Hier ist ein Beispiel für das Hochladen einer JMP-Datentabellendatei zu SAS und das anschließende Importieren mithilfe der SAS-Prozedur 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)
Überprüfen Sie das eingebettete Protokoll oder laden Sie die Datei herunter, um zu überprüfen, ob es funktioniert hat.
Nachfolgend finden Sie eine Upload-Strategie mit DataFrames. Wir konvertieren zuerst die JMP-Tabelle in einen DataFrame und laden sie dann mit dataframe2sasdata() hoch:
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'))
Überprüfen Sie das eingebettete Protokoll, um zu sehen, ob die Fitness-Tabelle in der Liste der WORK-Tabellen angezeigt wird.
Meiner Erfahrung nach ist die Verwendung ganzer Dateien für die Upload-/Download-Strategie tendenziell die schnellere der beiden Strategien. Außerdem werden dadurch Probleme bei der Datenkonvertierung oder -darstellung begrenzt. Andererseits werden DataFrames von anderen Python-Modulen weitgehend akzeptiert. Ich empfehle die Verwendung der Dateistrategie, sofern Sie nicht zusätzliche Python-Arbeiten an den Daten durchführen müssen.
Ausführen von SAS-Code
Im letzten Abschnitt haben wir die Funktion sas.submit() verwendet, um SAS-Code zum Importieren einer Datei auszuführen. Dies ist jedoch mit jedem beliebigen SAS-Code möglich. Sehen Sie sich die angehängte Datei saspy_cowboy_hat.jsl an, um ein Beispiel zu sehen, das die Verwendung von SASPy in einem JSL-Skript und die Ausführung von SAS-Code zum Erstellen und Anzeigen eines klassischen SAS-Diagramms demonstriert. Quelle: @bryan_boone und @ChrisHemedinger .
Ausblick auf JMP 19
Skripte, Add-Ins und Pipelines, die SASpy in JMP 18 verwenden, werden in JMP 19 weiterhin unterstützt. Das bedeutet, dass Sie bei der Arbeit mit SAS weiterhin jede erstellte Infrastruktur verwenden und darauf aufbauen können. Darüber hinaus bietet JMP 19 eine Reihe von Funktionen im Zusammenhang mit der SAS-Integration, die die in diesem Beitrag erwähnten Skripte und Techniken weiter verbessern. Einige bekannte Funktionen, wie der SAS-Exportdialog und verschiedene JSL-SAS-Integrationsfunktionen, werden zurückkehren. Sie basieren alle auf der Datenkonnektor-Infrastruktur, um die einfache Konfiguration, Freigabe und Nutzung von SAS-Verbindungen in Ihrem gesamten Unternehmen zu ermöglichen.
Sie haben derzeit JMP 18 und möchten zukünftige SAS-Integrationsfunktionen ausprobieren, bevor JMP 19 in Produktion geht? Eine hervorragende Möglichkeit, gezieltes Feedback und Anleitung zu geben, ist die Teilnahme am JMP 19 Early Adopter (EA)-Programm. Weitere Informationen finden Sie unter jmp.com/earlyadopter .
Durch die Integration der robusten Open-Source-Tools, die Python in JMP bietet, werden viele Möglichkeiten für den Zugriff auf und die Interaktion mit Daten verfügbar. Das vollständige SASPy-Demoskript finden Sie im Anhang dieses Beitrags.
Außerdem ein großes Dankeschön an Tom Weber für die Unterstützung von SASPy. Da es sich um ein Open-Source-Paket handelt, können Sie gerne Verbesserungen oder Vorschläge für SASPy bei github einbringen.
Viel Spaß beim Scripting!
Ressourcen
SASPy-Konfiguration
SASPy Python API
SASPy-Beispiel für Jupiter-Notebooks
Pandas-Dokumentation