私は以下のスクリプトを使用して、ロバスト平均とロバスト標準偏差を取得しています。100万行までは問題なく動作しますが、約500万行のテーブルでは45秒かかります。これを取得する他の効率的な方法はありますか?
Names Default To Here( 1 );
// 0. Guard: ensure at least one data table is open
If( N Table() == 0,
Throw( "No data table is open. Please open a data table first." )
);
dt = Current Data Table();
// 1. Ask user to select a numeric column
dlg = Column Dialog(
yCol = Col List( "Select a Numeric Column", Min Col( 1 ), Max Col( 1 ), Data Type( "Numeric" ) )
);
If( dlg["Button"] == -1, Throw( "User cancelled" ) );
selectedCol = dlg["yCol"][1];
colName = selectedCol << Get Name;
t1 = Tick Seconds();
// 2. Run Distribution with Robust Mean and Robust Std Dev enabled
dist = dt << Distribution(
Continuous Distribution(
Column( selectedCol ),
Outlier Box Plot Row Cutoff( 100000000 ),
Customize Summary Statistics(
Robust Mean( 1 ),
Robust Std Dev( 1 )
)
),
Invisible
);
Wait(0);
// 3. Extract Robust Mean and Robust Std Dev from the Summary Statistics table
distRep = dist << Report;
robustMean = .;
robustSigma = .;
Try(
// Navigate to the Summary Statistics outline box for the selected column
summBox = distRep[Outline Box( colName )][Outline Box( "Summary Statistics" )];
// Get the Name column (col 1) and Value column (col 2) from the table
nameCol = summBox[String Col Box( 1 )] << Get;
valueCol = summBox[Number Col Box( 1 )] << Get;
// Search for Robust Mean and Robust Std Dev rows by name
For( i = 1, i <= N Items( nameCol ), i++,
If( Contains( nameCol[i], "Robust Mean" ),
robustMean = valueCol[i]
);
If( Contains( nameCol[i], "Robust Standard Deviation" ),
robustSigma = valueCol[i]
);
);
,
Print( "Warning: Could not navigate report structure. Check outline box names." );
);
// 4. Display results
New Window( "Robust Statistics Results",
V List Box(
Text Box( "Column: " || colName ),
Text Box( "Robust Mean: " || (If( Is Missing( robustMean ),
"Not available", Char( robustMean, 10, 4 ) )) ),
Text Box( "Robust Std Dev: " || (If( Is Missing( robustSigma ),
"Not available", Char( robustSigma, 10, 4 ) )) )
)
);
// ------------------------
t2 = Tick Seconds();
Print( "Total Ticks: " || Char( Round( t2 - t1, 3 ) ) || " seconds" );
jmp関数内で必要な2つのロバスト統計量を計算する他の方法は見当たりませんが、大規模なテーブルでPythonインターフェースを使用した方が高速になるかどうか検討してみるのも良いでしょう。以下にその例を示します。
Names Default To Here(1);
// --- PARAMETERS ---
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp" );
colName = "npn1"; // <-- change to your column name
col = Column(dt, colName) << Get Values;
// Send column data to Python
Python Send( col );
c = 1.345; // Huber tuning constant
tol = 1e-6;
maxIter = 50;
// Run Python code
Python Submit(
"
import numpy as np
x = np.array(col, dtype=float)
x = x[~np.isnan(x)] # remove missing values
# --- Initialization ---
mu = np.median(x)
mad = np.median(np.abs(x - mu))
sigma = 1.4826 * mad if mad > 0 else np.std(x)
c = " || Char(c) || "
tol = " || Char(tol) || "
maxIter = " || Char(maxIter) || "
for _ in range(maxIter):
u = (x - mu) / sigma
# Huber weights
w = np.ones_like(u)
mask = np.abs(u) > c
w[mask] = c / np.abs(u[mask])
# Update mean
mu_new = np.sum(w * x) / np.sum(w)
# Update sigma
u = (x - mu_new) / sigma
sigma_new = sigma * np.sqrt(np.mean(np.minimum(u**2, c**2)))
# Check convergence
if abs(mu_new - mu) < tol and abs(sigma_new - sigma) < tol:
break
mu, sigma = mu_new, sigma_new
huber_mean = mu
huber_std = sigma
print( huber_mean, huber_std )
"
);
// Retrieve results from Python
huber_mean = Python Get(huber_mean);
huber_std = Python Get( huber_std);
show( huber_mean, huber_std);
これらの統計量を計算する目的は何ですか?JMPが分布プラットフォームで使用する方法(M推定値、計算負荷が高い)がご希望の方法でしょうか、それとももっと高速な方法(例えば中央値と四分位範囲)でも構いませんか?あるいは、事前にデータをサンプリングすることは可能でしょうか?