Esiste un modo più veloce per eseguire il loop?Ciao comunità JMP,
Sto analizzando quantità maggiori di dati, in genere 350.000 righe.
Per ogni riga, il codice esegue un ciclo per calcolare l'offset medio di " ID del wafer ". Sto cercando un modo più veloce per farlo.
C'è un modo per rendere l'elaborazione più veloce? Lo script corrente richiede ~1 ora r per completare il ciclo.
Names Default To Here( 1 );
dt1 = Data Table( "Reference Data Table.jmp" );
dt2 = Data Table("Data table");
Col_List1 = dt2 << Get Column Names( "String" );
Summation(
c = 1,
N Col( dt2 ) - 1,
values = [];
name = Column( dt2, c ) << Get Name;
If( Contains( name, "Currents" ) | Contains( name, "Voltage" ) | Contains( name, "Resistance" ),
rows = dt1 << Get Rows Where( :tests == name );
col = Column( dt2, c );
col mean = Col Mean( col );
For Each Row(
dt2,
mean = dt1:Mean[rows];
measure = mean - Col Mean( As Column( dt2, c ), :Wafer ID );
values |/= col[] + measure
;
);
col << Set Values( values );
);
0
);Modellazione statistica avanzataAutomazione e scriptingAccesso ai datiRi: Esiste un modo più veloce per eseguire il loop?Ecco il mio tentativo, le due tabelle in basso "stacked_table" e "summary_table_delta_by_wafer" potrebbero essere la forma giusta per questo.
È veloce in meno di 1 secondo per tutto
(Tempo HP() - inizio) / 1000000 = 0,664238;
Names Default To Here(1);
dt_ref = Open("$DOWNLOADS/Reference data table.jmp", invisible);
dt_dt = Open("$DOWNLOADS/Data table.jmp", invisible);
dt_dt << clear select;
dt_ref << clear select;
start = Hp Time();
curr_col_names_list = dt_dt << Get Column Names("string");
obj = dt_dt << Tabulate(
Show Control Panel( 0 ),
Add Table(
Column Table(
Analysis Columns(
eval list(curr_col_names_list)
),
Statistics( Mean )
),
Row Table( Grouping Columns( :Wafer ID ) )
)
);
my_new_table = obj << Make Into Data Table;
curr_col_names_list = my_new_table << Get Column Names("string");
transposed_table = my_new_table << Transpose(
columns(
eval list(curr_col_names_list)
),
Label( :Wafer ID ),
Output Table( "transposed_table" )
);
transposed_table << new column ("join_key"
,char
,formula(
regex(:Label,"\(([^\)]+)\)", "\1")
)
);
transposed_table_join = (
transposed_table << Join(
With( dt_ref )
,Match Columns( :join_key = :Tests),
,Merge same name columns
,output table("transposed_table_join")
)
);
// clean up
close(transposed_table,nosave);
close(my_new_table,nosave);
transposed_table_join << delete columns(:"Match Flag", :"Label","join_key");
transposed_table_join:"Mean" << Set Name( "Ref_Value" );
curr_col_names_list = transposed_table_join << Get Column Names("string");
matches_i_dont_want_to_stack = {"Tests","Ref_Value"};
clean_col_list = Associative Array(curr_col_names_list) << Remove(Associative Array(matches_i_dont_want_to_stack)) << get keys;
stacked_table = transposed_table_join << Stack(
columns( clean_col_list ),
Source Label Column( "Wafer_ID" ),
Stacked Data Column( "Measured_Value" ),
Output Table( "stacked_table" )
);
//Is this the formula you wanted on each value? A-B?
stacked_table << new column ("delta"
,numeric
,continuous
,formula(
(:Ref_Value -:Measured_Value)
)
);
//stacked table and final summary_table_delta_by_wafer seems like the useful combo here.
close(transposed_table_join,nosave);
//final output?
summary_table_delta_by_wafer = stacked_table << Transpose(
columns( :delta ),
By( :Wafer_ID ),
Label( :Tests ),
Output Table( "summary_table_delta_by_wafer" )
);
show((Hp Time() - start)/1e6);
Ri: Esiste un modo più veloce per eseguire il loop?Grazie Jarmo!<3 
Ri: Esiste un modo più veloce per eseguire il loop?Speriamo che i calcoli siano corretti. Non è lo script più semplice ma è in qualche modo ottimizzato per la velocità (sul mio portatile il calcolo di una colonna ha richiesto 200 ms, quindi in totale circa 6 secondi).
Names Default To Here(1);
dt_ref = Open("$DOWNLOADS/Reference data table.jmp", invisible);
dt_dt = Open("$DOWNLOADS/Data table.jmp", invisible);
dt_dt << clear select;
dt_ref << clear select;
aa_means = Associative Array(Column(dt_ref, "Tests"), Column(dt_ref, "Mean"));
col_list = Filter Each({col_name}, dt_dt << Get Column Names("String"),
Contains({"Currents", "Voltage", "Resistance"}, Word(1, col_name));
);
dt_dt << Add Row(1, At Start);
dt_dt << Begin Data Update;
For Each({col_name, idx}, col_list,
start = Hp Time();
Eval(Eval Expr(
Column(dt_dt, col_name) << Set Each Value(
//AsColumn(col_name) + aa_means[col_name] - Col Mean(AsColumn(col_name), :Wafer ID);
//Col Mean(Expr(Name Expr(AsColumn(col_name))), :Wafer ID);
//Col Mean(:Currents A17, :Wafer ID);
Expr(Name Expr(AsColumn(col_name)))+ Expr(aa_means[col_name]) - Col Mean(Expr(Name Expr(AsColumn(col_name))), :Wafer ID);
);
));
show((Hp Time() - start)/1e6);
);
dt_dt << Delete Row(1);
dt_dt << End Data Update;
//Summarize(dt_dt, b = by(:WAFER ID), m = Mean(:Currents A17));
//show(b,m, Col Mean(:Currents A17));
Ho dovuto aggiungere 1 riga all'inizio e rimuoverla in seguito per evitare strani problemi di calcolo quando si utilizza << Imposta ogni valore (potrebbero essere solo mie espressioni) ed è per questo che nel codice sono presenti alcune strane righe commentate. Contatterò l'assistenza JMP a riguardo quando avrò tempo
Modifica: ticket creato TS-00036082. A seconda della risposta che otterrò, scriverò un post separato riguardo al Col Mean
Ri: Esiste un modo più veloce per eseguire il loop?Ah... mi è mancato il col[] nel tuo script. Scriverò presto la nuova versione
Ri: Esiste un modo più veloce per eseguire il loop?....
Ri: Esiste un modo più veloce per eseguire il loop?L'uso del riepilogo (o del riepilogo se non è necessaria la tabella dati) dovrebbe essere abbastanza veloce (è possibile unire/aggiornare la tabella di riepilogo per dati di grandi dimensioni, se necessario)
Names Default To Here(1);
dt_ref = Open("$DOWNLOADS/Reference data table.jmp", invisible);
dt_dt = Open("$DOWNLOADS/Data table.jmp", invisible);
dt_dt << clear select;
dt_ref << clear select;
aa_means = Associative Array(Column(dt_ref, "Tests"), Column(dt_ref, "Mean"));
col_list = Filter Each({col_name}, dt_dt << Get Column Names("String"),
Contains({"Currents", "Voltage", "Resistance"}, Word(1, col_name));
);
dt_summary = dt_dt << Summary(
Group(:Wafer ID),
Mean(Eval(col_list)),
Freq("None"),
Weight("None"),
statistics column name format("column"), // this is important here
Link to original data table(0)
);
For Each({col_name}, col_list,
Eval(EvalExpr(
Column(dt_summary, col_name) << Set Each Value(
aa_means[col_name] - AsColumn(col_name)
);
));
);
Ricordatevi di controllare che i valori siano corretti
Ri: Esiste un modo più veloce per eseguire il loop?Sì, correggi una media per wafer. Sì, vorrei elaborarlo tutto in una volta perché sto sviluppando uno script che funge da strumento multifunzione per il mio team. Qualsiasi suggerimento sarebbe apprezzato jarmo
Ri: Esiste un modo più veloce per eseguire il loop?C'è una necessità specifica di avere tutte quelle 350k righe se alla fine ti ritrovi con 4 valori per colonna (se ho capito bene il codice), una media per wafer per colonna? Potresti eventualmente utilizzare Summary per creare una tabella molto più piccola.