저는 아래 스크립트를 사용하여 강건한 평균과 강건한 표준 편차를 계산하고 있습니다. 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 내에서는 필요한 두 가지 강력한 통계량을 계산하는 다른 방법이 없는 것 같습니다. 하지만 대규모 테이블에서 속도가 더 빠른지 확인하기 위해 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가 Distribution 플랫폼에서 사용하는 방법(M-추정기, 계산량이 많음)이 원하시는 방법인가요, 아니면 더 빠르고 효율적인 다른 방법(예: 중앙값 및 사분위 범위)을 사용할 수 있을까요? 아니면 데이터를 먼저 샘플링하는 방법은 어떨까요?