Problema con lo script per eliminare le misurazioni ridondanti specifiche per determinate condizioniHo una tabella dati composta da più righe di misurazioni individuali in serie che sto ritagliando prima di eseguire una funzione di suddivisione della tabella, tuttavia ho un problema con alcune misurazioni ridondanti che vorrei rimuovere ma il codice corrente mi che sto utilizzando è estremamente lento e probabilmente inefficiente per ciò di cui ho bisogno.
Informazioni di base:
- Ogni riga è il risultato di una misurazione automatizzata individuale su un pezzo di materiale eseguita in serie e produce un report con le seguenti colonne:
- Un ID parte univoco assegnato a ogni singolo pezzo di materiale [ PartID ]
- L'ID lotto associato alla materia prima utilizzata per creare il singolo pezzo di materiale [LotID]
- Il valore di misurazione effettivo per la misurazione eseguita [Valore]
- Risultato della misurazione assegnato in base al valore di misurazione (Pass/Fail/Rework) [Risultato]
- Timestamp della misurazione [Data_Creazione]
La mia attrezzatura produce dozzine di righe di misurazioni per pezzo di materiale ed elabora migliaia di pezzi di materiale per rapporto: tali rapporti vengono quindi inseriti in JMP come tabella dati originale.Ogni report contiene anche più lotti, quindi la tabella dati ha più riferimenti a "PartID = 1" perché a ogni lotto viene assegnato un numero sequenziale che inizia da 1, quindi devo utilizzare sia PartID che LotID per fare riferimento a un determinato pezzo di materiale.Nel caso in cui il risultato sia "Rilavorazione", l'apparecchiatura di misurazione interrompe qualsiasi ulteriore misurazione su quel singolo pezzo di materiale, riorienta il pezzo di materiale e lo riporta all'inizio della linea rimisurando tutti i test precedenti sul materiale ma mantenendo comunque lo stesso ID parte univoco associato al pezzo di materiale.
Risultato desiderato:
Desidero utilizzare lo script per esaminare la tabella dati ed eliminare tutte le misurazioni fino al risultato della rielaborazione (incluso), poiché dopo la rielaborazione tutte le misurazioni vengono ripetute e la rielaborazione può influenzare i valori di misurazione.Per fare ciò sto attualmente utilizzando lo script JSL per scorrere ogni riga e fare quanto segue:
- Identificare se il risultato è "Rilavorazione"; se è così allora procedi come segue:
- Identificare il PartID per il pezzo di materiale specificato come "xPartID"
- Identificare il LotID per il pezzo di materiale specificato come "xLot"
- Identificare Date_Created per la misurazione specificata come "xDate"
- Seleziona ed elimina tutte le righe in cui (PartID = xPartID) e (LotID = xLot) e (Date_Created <= xDate)
- Se il risultato non è "Rilavorazione", esci dal ciclo, non è necessario continuare.
Continuo ad avere rallentamenti estremi e sostanzialmente il codice porta al crash del programma.Se lo eseguo passo dopo passo sembra funzionare, ma se lo lascio eseguire alla fine muore. Ecco il codice effettivo:
//Recoding the two potential "Rework" results into a shared value "aRework"; putting the letter "a" in front of it so if I sort by the column ascending then all of these values are at the start of the list, to hopefully make it easier and faster to process them.
dt << Recode Column(
dt:result,
{Map Value(
_rcOrig,
{"FailOnHighRework", "aRework",
"FailOnLowRework", "aRework"},
Unmatched( _rcNow )
)},
Update Properties( 1 ),
Target Column( :result )
);
//Sorting the table using the result column after the recode, so all of the rework rows are at the start of the table
SortColumn = "result";
dt << Sort( By( :result ), Replace Table, Order( Ascending ), Suppress formula evaluation( 1 ) );
//now run the row-by-row script
dt << begin data update;
for each row(
If( :result == "aRework",
xRow = Row();
xPartID=:PartID[Row()];
xLot=:lot[Row()];
xDate=:date_created[Row()];
dt <<SELECT where=""></SELECT>Sono su JMP 16.2.0 (570548).
Personalizzazione di massaRi: Problema con lo script per eliminare misurazioni ridondanti specifiche per determinate condizioniEcco una versione dello script che viene stampata dopo che sono state elaborate 100 righe in dt
dt = Current Data Table();
dt << select where( :result == "aRework" );
dt2 = dt << subset( selected rows( 1 ), selected columns( 0 ) );
// Remove aRework rows from original table
dt << delete rows;
// Loop across the aRework table and delete rows in orininal table
//dt << begin data update;
start = 1;
end = 0;
alldt2 = N Rows( dt2 );
While( N Rows( dt2 ) > 100,
TotalRows = N Rows( dt2 );
If( TotalRows > 100,
TotalRows = 100
);
end = end + TotalRows;
For( i = 1, i <= TotalRows, i += 1,
dt << select where(
dt:partid == dt2:PartID[i] & dt:lot == dt2:Lot[i] & dt:date_created <= dt2
:Date_created[i]
);
If( N Rows( dt << get selected rows ) > 0,
dt << delete rows
);
);
//dt << end data update;
dt2 << delete rows( 1 :: 100 );
Show(
"Rows " || Char( start ) || " to " || Char( end ) || " of " || Char( alldt2 ) ||
" processed"
);
);
Close( dt2, nosave );
Puoi anche configurarlo per elaborare solo un numero x di righe e quindi eseguirlo nuovamente per elaborare più righe.
Ri: Problema con lo script per eliminare misurazioni ridondanti specifiche per determinate condizioniCiao,
Lo script sembra funzionare come previsto e, se eseguito su un set di dati molto piccolo (10.000 righe in totale), sembra buono e veloce, tuttavia riscontro rallentamenti significativi con il set di dati effettivo con cui sto lavorando (1,6 milioni di righe ) in modo tale che non riesco a capire se sta uccidendo il programma (non risponde, lo ha lasciato in esecuzione per circa 1,5 ore ed era ancora apparentemente in esecuzione ma il processo non ha risposto e alla fine ha dovuto "Terminare l'attività" tramite il task manager) - qualche consiglio su come migliorare?L'esecuzione su 10k righe ha richiesto forse <10 secondi, quindi spero che per 1,6 milioni ci vorrebbero forse 30 minuti se si ridimensionasse linearmente, ma non sembra essere il caso.
Sto caricando un sottoinsieme ripulito della tabella dati come riferimento con il miglioramento dello script suggerito salvato nella tabella dati.Nella tabella ripulita era presente un solo LotID, ma in genere non è così e serve solo a ridurre al minimo la dimensione totale del file da caricare.
Ecco la versione corrente dello script che sto cercando di eseguire sulla tabella:
dt = current data table();
dt << select where( :result == "aRework" );
dt2 = dt << subset( selected rows( 1 ), selected columns( 0 ) );
// Remove aRework rows from original table
dt << delete rows;
// Loop across the aRework table and delete rows in orininal table
dt << begin data update;
TotalRows=N Rows(dt2);
For( i = 1, i <= N Rows( dt2 ), i+=1,
dt << select where(dt:partid == dt2:PartID[i] & dt:lot == dt2:Lot[i] & dt:date_created <= dt2:Date_created[i]);
If( N Rows( dt << get selected rows ) > 0,
dt << delete rows
);
);
dt << end data update;
close( dt2, nosave );
Ancora una volta, grazie mille per l'aiuto!
Ri: Problema con lo script per eliminare misurazioni ridondanti specifiche per determinate condizioniCiao e grazie!
Adesso sto eseguendo lo script sulla mia tabella dati; Penso che tu avessi decisamente ragione nel mio scorrere le righe su una tabella in cui la riga veniva considerata attivamente eliminata, il che probabilmente stava incasinando la logica del ciclo.
Sto eseguendo il codice sulla mia tabella dati ora e riferirò.Proverò anche a vedere se riesco a ripulire alcuni snippet della mia tabella dati per consentirmi di includerla in questo post.Grazie mille per la sua assistenza!
Ri: Problema con lo script per eliminare misurazioni ridondanti specifiche per determinate condizioniCredo che tu stia riscontrando un problema in cui stai scorrendo una tabella di dati utilizzando For Each Row e continui a cambiare la tabella che stai scorrendo eliminando righe e il ciclo si sta confondendo.
Ecco un pezzo di codice non testato che penso eliminerà il problema e dovrebbe funzionare in modo abbastanza efficiente.
Names Default To Here( 1 );
//Recoding the two potential "Rework" results into a shared value "aRework"; putting the letter "a" in front of it so if I sort by the column ascending then all of these values are at the start of the list, to hopefully make it easier and faster to process them.
dt << Recode Column(
dt:result,
{Map Value( _rcOrig, {"FailOnHighRework", "aRework", "FailOnLowRework", "aRework"}, Unmatched( _rcNow ) )},
Update Properties( 1 ),
Target Column( :result )
);
dt << select where( :result == "aRework" );
dt2 = dt << subset( selected rows( 1 ), selected columns( 0 ) );
// Remove aRework rows from original table
dt << delete rows;
// Loop across the aRework table and delete rows in orininal table
For( i = 1, i <= N Rows( dt2 ), i++,
dt << select where(
(dt:partid == dt2:PartID[i] & dt:lot == dt2:Lot[i] & dt:date_created <= dt2:Date_created[i]);
If( N Rows( dt << get selected ) > 0,
dt << delete rows
);
)
);
close( dt2, nosave );
Non avevo una tabella dati di esempio con cui lavorare, quindi il codice non è stato testato, ma l'approccio dovrebbe consentire di risolvere eventuali problemi e farlo funzionare.