你好,
我正在尝试使用 JMP 通过脚本打开 hdf5 文件。我可以使用 Open() 命令成功打开它:
blobpath = "/Documents/myblob";
dtblob_lis = Open(blobpath);
但我收到一个弹出窗口询问我想要打开哪个数据集:

我的问题是:Open() 命令中是否有一个选项,我可以使用这个选项来指定我想打开 blob 中的哪个数据集,并避免弹出窗口?谢谢。
或者:使用 h5py。
从 JMP18 开始非常顺利:)
这是我尝试的第一件事。不,日志或创建的表中没有明显的操作记录。
这是一个猜测,但根据关于自动打开 hdf5 文件的讨论,Python 集成可能是答案。 @briancorcoran
您不必使用 JMP 的 Python 集成来管理使用 Python 的文件打开/转换,只需创建一个可以从命令行运行的 Python 脚本(使用 Run Program()),该脚本接受您需要的输入(至少是文件路径),将其保存为 .csv,然后在 JMP 中打开该 .csv。这就是我在 JMP18 之前在 JMP 中使用 Python 的方式(现在仍然时不时地这样做)。当然,您可以尝试在 18 之前的版本中使用 JMP 的 Python 集成,但我不会费心,只会从命令行运行它。
您可以使用 JSL 列表指定要打开的成员来打开 HDF5 数据集中的单个项目。例如,以下方法对我有用(同时指定文件扩展名):
打开(“d:\testdata\HDF5\hdf5data.h5”,{“/g2/float”});
对于你来说,它可能看起来像:
打开(“/Documents/myblob.h5”,{“/CSIG_RAW_IMG_OFF/F0/FrameNumbers”,“/CSIG_RAW_IMG_OFF/F0/Frames”});
我希望这能有所帮助。
布莱恩·科克伦
JMP 开发
我一直在寻找在 Python 和 JMP 17 之间传输数据的更快、更有效的方法,因为 Pandas 和 JMP 在读取/写入 CSV 时都非常慢,甚至 GetTable() 函数似乎也在后台使用 CSV,至少在 JMP 17 中是这样。Pandas 的 to_hdf 函数不起作用,因为它没有将字符串数据存储在符合 HDF 的数据集中,而是使用一些自定义的诡计将 Numpy 数组存储为字符串,这不仅空间效率低下,而且还会锁定您使用 Python 读取它。
我编写了一个自定义概念验证 Python 代码,使用 h5py 保存 .h5 表,并编写了 JSL 代码读取该表并从单独的数据集重建原始表。
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);
我禁用了尝试重建原始列顺序的代码,因为对于宽表来说,这非常非常慢。另外,请注意,我没有考虑没有特定类型列的情况。如果您在意这一点,那么在 JSL 端需要做一些额外的工作。
结果:对于一个包含 80 行、115,791 列的数据表,通常情况下,Pandas 需要 20 秒才能将其保存为 csv 文件,JMP 需要 24 秒才能打开,而我的脚本保存只需 1.7 秒,JMP 则需要 11.5 秒才能打开。此外,使用 gzip 压缩后,文件大小从 88.8 MB 减少到 24.5 MB。这意味着时间节省了 70%,空间节省了 72%。