JMP 18 Python jmp.DataTable 與 pandas.DataFrameJMP 18 在 Python 整合中帶來了強大的新功能。包括 Python 3.11 的嵌入式版本、套件安裝支援、可以運行純 Python 腳本的 Python 感知腳本編輯器、提供 Python 訪問 JMP 功能的導入 jmp包、增強的錯誤報告和腳本索引支援記錄並提供新功能的範例“ Python」類別。

這裡的重點是 jmp.DataTable 物件以及 JMP 18 對Python Send (dt)和Python Get(df)所做的變更。其中「dt」是資料表,「df」是 pandas.DataFrame。
JMP 14-17 提供了使用 JSL 指令Python Send( dt ) 將 JMP 資料表的副本傳送到 Python 環境的功能; 。其幕後運作方式是,JMP 將資料表寫入檔案系統中的臨時 CSV 文件,然後呼叫 pandas 將 CSV 檔案從磁碟讀取到 DataFrame 中。這適用於小文件,但不適用於較大的資料。首先,是必須使用檔案系統進行資料傳輸的問題。其次,從二進位到文字然後再返回二進位可能會損失精確度。其次,CSV 檔案通常比原始二進位資料大得多。最後,您擁有 Python 中的資料副本,而不是操作原始表的方法。使用Python Get ( df ) 將 Python 處理後的資料帶回 JMP 中;反向執行完全相同的過程。 Python 獲取(df);出於相容性原因,原樣保留。
18 新增, Python Get ( dt );檢索實際表的 JSL 的資料表引用。這是零複製操作。必要時Python Send( dt );不再創建 pandas.DataFrame。在 Python 中,你會得到一個 jmp.DataTable 對象,它是對 JMP 資料表。這也是零複製操作。它允許從Python直接存取、編輯和修改JMP資料表。您可以在建立新 JMP 表的過程中從 Python 建立 jmp.DataTable 物件。
下面是一個 JSL 腳本,利用 JMP 18.0 功能取得 JMP 資料表,新增一列,該列是來自 Python 的兩列的比率。在目前資料表上即時執行此操作。
// BigClass_hw_ratio.jsl
// Description: Show JMP 18 Python integration features
//
Names Default to Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
Python Send(dt);
Python Submit("\[
import jmp
# print some information on data table properites
print(dt.__class__)
print(dt.name)
print(f'nrows: {dt.nrows}')
print(f'ncols: {dt.ncols}')
# data table object columns may be indexed either by
# column name or index. Note: slice is only supported
# when using indexes. Slice on both columns and rows is supported.
for x in dt[0:]:
print( x.name )
# As is Python convention, indexing is 0-based
print( dt['name'][0] )
# create a new column based on data from the original data.
# Because JMP is column centric, the access to
# jmp.DataTable object is [column][row]
dt.new_column('H/W ratio', jmp.DataType.Numeric)
for idx in range(dt.nrows):
dt['H/W ratio'][idx] = dt['height'][idx] / dt['weight'][idx]
]\");

導致日誌輸出:
/*:
大班 nrows: 40 ncols: 5 姓名 年齡 性別 身高 體重 KATIE 0
現在讓我們展示直接從 Python 進行工作。下面是一個 Python 腳本,它打開“Big Class.jmp”,從 jmp.DataTable 物件在記憶體中建立一個 pandas 資料框,關閉“Big Class”,然後從 DataFrame 建立新的 JMP 資料表,最後在 JSL 中列印目前資料表的列名。當前表是剛剛在 Python 中建立的表。

# dt2pandas2dt.py
# Description: Example showing creating a pandas.DataFrame from a .jmp file,
# then creating a new data table from the data frame.
# This process happening live and in-memory.
#
import jmp
import numpy as np
import pandas as pd
from pandas.api.types import is_object_dtype, is_numeric_dtype, is_bool_dtype, is_string_dtype
# creating a Pandas dataframe from a JMP DataTable directly
dt = jmp.open(jmp.SAMPLE_DATA + "Big Class.jmp")
# create pandas DataFrame from Big Class
df = pd.DataFrame()
for idx in range( len(dt) ):
df[ dt[idx].name ] = np.array( dt[idx] )
print(df)
# we can close dt since we no longer need it open, we
# have everyting in df
dt.close(save=False)
# create JMP DataTable from pandas DataFrame
dt2 = jmp.DataTable('BC2', df.shape[0])
# get the column names from the data frame
names = list(df.columns)
# loop across the columns of the data frame
for j in range( df.shape[1] ):
# check if the coulumn data type is string or numeric
if is_string_dtype(df[ names[j] ] ):
dt2.new_column(names[j], jmp.DataType.Character )
else:
dt2.new_column(names[j], jmp.DataType.Numeric )
# populate the JMP column with data
dt2[j] = list(df.iloc[:,j])
# Just as JSL has a Python Submit(); to execute Python code
# the jmp object has a run_jsl() command to execute JSL from Python
jmp.run_jsl('''
Names Default to Here(1);
Current Data Table() << Get Column Names;
''')
有日誌輸出
/*:
name age sex height weight
0 KATIE 12.0 F 59.0 95.0
1 LOUISE 12.0 F 61.0 123.0
2 JANE 12.0 F 55.0 74.0
3 JACLYN 12.0 F 66.0 145.0
4 LILLIE 12.0 F 52.0 64.0
5 TIM 12.0 M 60.0 84.0
6 JAMES 12.0 M 61.0 128.0
7 ROBERT 12.0 M 51.0 79.0
8 BARBARA 13.0 F 60.0 112.0
9 ALICE 13.0 F 61.0 107.0
10 SUSAN 13.0 F 56.0 67.0
11 JOHN 13.0 M 65.0 98.0
12 JOE 13.0 M 63.0 105.0
13 MICHAEL 13.0 M 58.0 95.0
14 DAVID 13.0 M 59.0 79.0
15 JUDY 14.0 F 61.0 81.0
16 ELIZABETH 14.0 F 62.0 91.0
17 LESLIE 14.0 F 65.0 142.0
18 CAROL 14.0 F 63.0 84.0
19 PATTY 14.0 F 62.0 85.0
20 FREDERICK 14.0 M 63.0 93.0
21 ALFRED 14.0 M 64.0 99.0
22 HENRY 14.0 M 65.0 119.0
23 LEWIS 14.0 M 64.0 92.0
24 EDWARD 14.0 M 68.0 112.0
25 CHRIS 14.0 M 64.0 99.0
26 JEFFREY 14.0 M 69.0 113.0
27 MARY 15.0 F 62.0 92.0
28 AMY 15.0 F 64.0 112.0
29 ROBERT 15.0 M 67.0 128.0
30 WILLIAM 15.0 M 65.0 111.0
31 CLAY 15.0 M 66.0 105.0
32 MARK 15.0 M 62.0 104.0
33 DANNY 15.0 M 66.0 106.0
34 MARTHA 16.0 F 65.0 112.0
35 MARION 16.0 F 60.0 115.0
36 PHILLIP 16.0 M 68.0 128.0
37 LINDA 17.0 F 62.0 116.0
38 KIRK 17.0 M 68.0 134.0
39 LAWRENCE 17.0 M 70.0 172.0
//:*/
Names Default to Here(1);
Current Data Table() << Get Column Names;
/*:
{name, age, sex, height, weight}
未來的部落格文章中將提供更多範例。
JMP 18 帶來了許多新功能,包括改進的 Python 支援。其主要功能之一是直接從 Python 存取、修改和建立 JMP 資料表。這是透過 jmp.DataTable Python 物件完成的。這篇文章將展示如何從 JMP 資料表建立 pandas.DataFrame,以及如何從即時和記憶體中的 pandas.DataFrame 建立 JMP 資料表。
自動化和腳本編寫資料存取回覆:JMP® 18 中的新功能:Python jmp.DataTable 和 pandas.DataFrame現在,此功能已在今年的用戶大會上進行了演示,我可以與大家分享。
JMP 19 提供了對可移植資料框協定的支持,這使得我們只需一行程式碼就可以在 pandas 或任何其他相容資料框之間進行轉換。取得後請查看19 EA或19中的腳本索引。
import pandas as pd
import numpy as np
pandas_df = pd.DataFrame(
{
"A": 1.0,
"B": pd.Timestamp("20130102"),
"C": pd.Series(1, index=list(range(4)), dtype="float32"),
"D": np.array([3] * 4, dtype="int32"),
"E": pd.Categorical(["test", "train", "test", "train"]),
"F": "foo",
}
)
print(pandas_df)
dt = jmp.from_dataframe(pandas_df)
print(dt)
jmp 套件現在有一個 from_dataframe( df ) 方法,它將從記憶體中的資料框中建立一個 JMP 資料表。 Pandas 也支援可移植資料框協定。因為我們實作了接口,所以 pandas 可以直接從 jmp.DataTable 物件建立資料框。
import jmp
import pandas as pd
dt = jmp.open(jmp.SAMPLE_DATA + "Big Class.jmp")
pandas_df = (pd.api.interchange.from_dataframe(dt))
print(pandas_df)
其他支援資料幀協定的軟體包包括 Polars 和 Ibis。再次參閱 19 中的腳本索引以取得範例。
回覆:JMP® 18 新增功能:Python jmp.DataTable 與 pandas.DataFrame我最近安裝了 JMP 19.1.1,並嘗試了@Paul_Nelson上面描述的方法,使用了他提供的範例程式碼。我發現它仍然使用了中間的臨時 CSV 文件,並且在日誌中出現了以下訊息:
:16: Pandas4Warning: The Dataframe Interchange Protocol is deprecated.
For dataframe-agnostic code, you may want to look into:
- Arrow PyCapsule Interface: https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html
- Narwhals: https://github.com/narwhals-dev/narwhals
ValueError: ArrowCTypes for string columns must be UTF-8 Strings or UTF-8 Large Strings.
The above exception was the direct cause of the following exception:
SystemError:
returned a result with an exception set
進一步調查顯示, JMP 使用的資料幀交換協議似乎在 pandas 3.0 中已被棄用。
我的 JMP 實例中安裝了 pandas 3.0.2。我回滾到 pandas 2.2.3 後,日誌中的消息消失了,JMP 資料表也產生了,而沒有產生中間 CSV 檔案。
回覆:JMP® 18 新增功能:Python jmp.DataTable 與 pandas.DataFramePandas 3.0 帶來了一些問題。 Pandas 3.0 對字串列的處理方式從 2.x 版本升級到了 3.x 版本。這導致我們在處理字串列時出現錯誤,進而導致在使用 Pandas 3.0.x 和 JMP 19.x 時回退到 CSV 格式。我們已經在 JMP 20 中修復了這個問題,目前正在研究是否可以在 19.2 版本中發布。為此,我們不得不修改大量程式碼。