Salut,
J'essaie d'utiliser JMP pour ouvrir un fichier hdf5 à l'aide d'un script. Je peux l'ouvrir avec succès à l'aide de la commande Open() :
blobpath = "/Documents/myblob";
dtblob_lis = Open(blobpath);
mais j'obtiens une fenêtre contextuelle me demandant quel ensemble de données je souhaite ouvrir :

Ma question : existe-t-il une option dans la commande Open() que je pourrais utiliser pour spécifier quel ensemble de données dans le blob je souhaite ouvrir et éviter la fenêtre contextuelle ? Merci.
... et existe-t-il un moyen d'enregistrer l'action ?
comme alternative : utiliser h5py.
très fluide depuis JMP18 : )
C'est la première chose que j'ai essayé. Non, il n'y a aucun enregistrement apparent des actions dans le journal ou dans les tables qui sont créées.
Malheureusement, mon organisation n'a pas encore adopté JMP18.
LearnBot : pareil.
rafraîchissant et honnête : )

Il s'agit d'une supposition, mais d'après la discussion sur l'automatisation de l'ouverture d'un fichier hdf5, l'intégration Python pourrait être la réponse. @briancorcoran
Vous n'avez pas besoin d'utiliser l'intégration Python de JMP pour gérer l'ouverture/la conversion de fichiers avec Python, créez un script Python que vous pouvez exécuter à partir de la ligne de commande (en utilisant Run Program()) qui prend les entrées dont vous avez besoin (au moins le chemin du fichier), l'enregistre au format .csv, puis ouvre ce fichier .csv dans JMP. C'est ainsi que j'utilisais Python avant JMP18 dans JMP (et je le fais encore de temps en temps). Vous pouvez bien sûr essayer d'utiliser l'intégration Python de JMP dans les versions antérieures à 18, mais je ne m'en soucierais pas et je l'exécuterais simplement à partir de la ligne de commande.
Vous pouvez ouvrir des éléments individuels dans l'ensemble de données HDF5 en utilisant une liste JSL pour spécifier les membres à ouvrir. Par exemple, ce qui suit a fonctionné pour moi (en spécifiant également l'extension de fichier) :
ouvrir("d:\testdata\HDF5\hdf5data.h5", {"/g2/float"});
Dans votre cas, cela pourrait ressembler à :
open("/Documents/myblob.h5", {"/CSIG_RAW_IMG_OFF/F0/FrameNumbers", "/CSIG_RAW_IMG_OFF/F0/Frames"});
J'espère que cela aide.
Brian Corcoran
Développement JMP
Brian,
Où cette capacité est-elle documentée ?
C'est exactement la solution que je cherchais. Ça marche. Merci.
Je cherchais des moyens plus rapides et plus efficaces de transférer des données entre Python et JMP 17, car pandas et JMP sont assez lents à lire/écrire du CSV, et même la fonction GetTable() semble utiliser du CSV sous le capot, du moins dans JMP 17. La fonction to_hdf de Pandas ne fonctionne pas car au lieu de stocker des données de chaîne dans un ensemble de données compatible HDF, elle utilise à la place des manigances personnalisées pour stocker un tableau Numpy sous forme de chaîne, ce qui est non seulement inefficace en termes d'espace mais vous oblige également à le lire avec Python.
J'ai écrit un code Python de preuve de concept personnalisé qui enregistre une table .h5 à l'aide de h5py et un code JSL qui lit la table et reconstruit la table d'origine à partir des ensembles de données séparés.
import pandas as pd
import numpy as np
from pathlib import Path
import h5py
from time import perf_counter
last_time = perf_counter()
compression = "gzip"
def log_time(msg):
global last_time
current_time = perf_counter()
elapsed_time = current_time - last_time
print(f"{elapsed_time:1.3f} s: {msg}")
last_time = current_time
# read dataframe (just for the development example)
df = pd.read_csv(Path(__file__).parent / "my_table.csv")
log_time("Read df")
string_columns = df.select_dtypes(include=["object"]).columns
# min_itemsize = {col: df[col].str.len().max() for col in string_columns}
max_string_length = np.max([df[col].str.len().max() for col in string_columns]) if len(string_columns) > 0 else 1
max_string_column_length = np.max([len(col) for col in string_columns]) if len(string_columns) > 0 else 1
log_time("max_string_length =" + str(max_string_length))
float_columns = df.select_dtypes(include=["float"]).columns
max_float_column_length = np.max([len(col) for col in float_columns]) if len(float_columns) > 0 else 1
log_time("max_float_column_length =" + str(max_float_column_length))
int_columns = df.select_dtypes(include=["int"]).columns
max_int_column_length = np.max([len(col) for col in int_columns]) if len(int_columns) > 0 else 1
log_time("max_int_column_length =" + str(max_int_column_length))
max_column_length = np.max(
[max_float_column_length, max_int_column_length, max_string_column_length]
)
log_time("max_column_length =" + str(max_column_length))
file = h5py.File(Path(__file__).parent / "sample.h5", "w")
log_time("Opened h5 file")
string_data = df[string_columns].astype(str).values
log_time("Converted string data to str")
string_data_ascii = np.array(
[[s.encode("ascii", "ignore") for s in row] for row in string_data]
)
log_time("Converted string data to ascii")
file.create_dataset(
"string_data",
data=string_data_ascii,
dtype=f"S{max_string_length}",
compression=compression,
)
log_time("Created string_data dataset")
file.create_dataset(
"string_columns",
data=np.array(string_columns, dtype=f"S{max_string_column_length}"),
compression=compression,
)
log_time("Created string_columns dataset")
file.create_dataset(
"float_data", data=df[float_columns].values, dtype="f4", compression=compression
)
log_time("Created float_data dataset")
file.create_dataset(
"float_columns",
data=np.array(float_columns, dtype=f"S{max_float_column_length}"),
compression=compression,
)
log_time("Created float_columns dataset")
file.create_dataset(
"int_data", data=df[int_columns].values, dtype="i4", compression=compression
)
log_time("Created int_data dataset")
file.create_dataset(
"int_columns",
data=np.array(int_columns, dtype=f"S{max_int_column_length}"),
compression=compression,
)
log_time("Created int_columns dataset")
file.create_dataset(
"column_order",
data=np.array(
df.columns,
dtype=f"S{max_column_length}",
),
compression=compression,
)
log_time("Created column_order dataset")
file.flush()
file.close
CloseAll(datatables, nosave);
last_time = TickSeconds();
log_time = Function({msg},
now = TickSeconds();
print(Char(now - last_time) || " - " || Char(msg));
last_time = now;
);
hdf5_file_path = "my_table.h5";
dataset_names = {
// "/column_order",
"/float_columns",
"/float_data",
"/int_columns",
"/int_data",
"/string_columns",
"/string_data"
};
// Open the hdf file
hdf5_file = Open(hdf5_file_path, dataset_names, invisible);
log_time("Opened HDF5 file: " || hdf5_file_path);
// Get list
// columns = As Column(DataTable("-column_order"), "Column 1"n) << get as matrix;
string_columns = As Column(DataTable("-string_columns"), "Column 1"n) << get as matrix;
float_columns = As Column(DataTable("-float_columns"), "Column 1"n) << get as matrix;
int_columns = As Column(DataTable("-int_columns"), "Column 1"n) << get as matrix;
Close(DataTable("-string_columns"), nosave);
Close(DataTable("-float_columns"), nosave);
Close(DataTable("-int_columns"), nosave);
log_time("Got columns");
dt_int = DataTable("-int_data");
ForEach({cname, i}, int_columns,
Column(dt_int, "Column " || Char(i)) << SetName(cname)
);
log_time("Assembled int table");
dt_float = DataTable("-float_data");
ForEach({cname, i}, float_columns,
Column(dt_float, "Column " || Char(i)) << SetName(cname)
);
log_time("Assembled float table");
dt_string = DataTable("-string_data");
ForEach({cname, i}, string_columns,
Column(dt_string, "Column " || Char(i)) << SetName(cname)
);
log_time("Assembled string table");
dt_string << Update(
With( dt_int ),
Replace Columns in Main Table( None )
);
Close(dt_int, nosave);
dt_string << Update(
With( dt_float ),
Replace Columns in Main Table( None )
);
Close(dt_float, nosave);
log_time("Combined table");
// For( i = N Items( columns ), i >= 1, i--,
// Eval( Parse( "combined_dt << Move Selected Columns(\!"" || columns[i] || "\!"n, To first )" ) )
// );
// log_time("Moved columns");
dt_string << SetName("my_table");
dt_string << ShowWindow(1);
J'ai désactivé le code qui tente de reconstruire l'ordre d'origine des colonnes, car c'est extrêmement lent pour les tableaux larges. Notez également que je n'ai pas pris en compte le cas où il n'y a pas de colonnes d'un type particulier. Cela nécessitera un peu de travail supplémentaire côté JSL si cela vous intéresse.
Résultats : Pour un tableau de données de 80 lignes et 115 791 colonnes, dont l'enregistrement au format CSV prendrait normalement 20 secondes à Pandas et l'ouverture à JMP 24 secondes, il a fallu 1,7 seconde à mon script pour l'enregistrer et 11,5 secondes à JMP pour l'ouvrir. De plus, la taille du fichier est passée de 88,8 Mo à 24,5 Mo grâce à la compression gzip. Cela représente un gain de temps total de 70 % et un gain d'espace de 72 %.