Problème avec le script pour supprimer les mesures redondantes spécifiques à certaines conditionsJ'ai une table de données composée de plusieurs lignes de mesures individuelles en série que je coupe avant d'exécuter une fonction de fractionnement de table. Cependant, j'ai un problème avec certaines mesures redondantes que je voudrais supprimer, mais le code actuel est que j'utilise est extrêmement lent et probablement inefficace pour ce dont j'ai besoin.
Informations d'arrière-plan:
- Chaque ligne est le résultat d'une mesure individuelle automatisée sur une pièce de matériau réalisée en série et produit un rapport avec les colonnes suivantes :
- Un identifiant de pièce unique attribué à chaque pièce de matériau [PartID]
- L'ID de lot associé à la matière première utilisée pour créer le morceau de matériau individuel [ LotID ]
- La valeur de mesure réelle pour la mesure effectuée [ Valeur ]
- Résultat de mesure attribué en fonction de la valeur de mesure (Réussite/Échec/Retravail) [ Résultat ]
- Horodatage de la mesure [Date_Created]
Mon équipement produit des dizaines de lignes de mesures par pièce de matériau et traite des milliers de pièces de matériau par rapport. Ces rapports sont ensuite introduits dans JMP en tant que tableau de données d'origine.Chaque rapport contient également plusieurs lots, de sorte que le tableau de données comporte plusieurs références à "PartID = 1" car chaque lot reçoit un numéro séquentiel commençant à 1, je dois donc utiliser à la fois PartID et LotID pour faire référence à un élément de matériau donné.Dans le cas où le résultat est « Retravailler », l'équipement de mesure arrête toute autre mesure sur ce morceau de matériau individuel, réoriente le morceau de matériau et le ramène au début de la ligne en remesurant tous les tests précédents sur le matériau tout en conservant le même identifiant de pièce unique associé au morceau de matériau.
Résultat souhaité:
Je souhaite utiliser un script pour parcourir le tableau de données et éliminer toutes les mesures jusqu'au résultat de la retouche (et y compris), car après la retouche, toutes les mesures sont répétées et la retouche peut affecter les valeurs de mesure.Pour ce faire, j'utilise actuellement le script JSL pour parcourir chaque ligne et procéder comme suit :
- Identifiez si le résultat est « Rework » ; si c'est le cas, procédez comme suit :
- Identifiez le PartID du morceau de matériel donné comme "xPartID".
- Identifiez le LotID du morceau de matériau donné comme "xLot".
- Identifiez le Date_Created pour la mesure donnée comme "xDate"
- Sélectionnez et supprimez toutes les lignes où (PartID = xPartID) et (LotID = xLot) et (Date_Created <= xDate)
- Si le résultat n'est pas "Rework", alors sortez de la boucle, pas besoin de continuer.
Je continue à avoir des ralentissements extrêmes et, fondamentalement, le code entraîne le blocage du programme.Si je l'exécute étape par étape, cela semble fonctionner, mais si je le laisse exécuter, il finit par mourir. Voici le code réel :
//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>Je suis sur JMP 16.2.0 (570548).
Personnalisation de masseRe : Problème avec le script pour supprimer les mesures redondantes spécifiques à certaines conditionsVoici une version du script qui s'imprime toutes les 100 lignes de 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 );
Vous pouvez également le configurer pour traiter uniquement un nombre x de lignes, puis le réexécuter pour traiter davantage de lignes.
Re : Problème avec le script pour supprimer les mesures redondantes spécifiques à certaines conditionsBonjour,
Le script semble fonctionner comme prévu, et lorsqu'il est exécuté sur un très petit ensemble de données (10 000 lignes au total), il semble être bon et rapide, mais je rencontre des ralentissements importants avec l'ensemble de données réel avec lequel je travaille (1,6 million de lignes). ) de telle sorte que je ne peux pas dire s'il tue le programme (ne répond pas, l'a laissé fonctionner pendant environ 1,5 heure et il semblait toujours en cours d'exécution mais le processus n'a pas répondu et a finalement dû le "Terminer la tâche" via le gestionnaire de tâches) - des conseils pour s'améliorer ?L'exécution sur 10 000 lignes a pris peut-être moins de 10 secondes, donc j'espère que pour 1,6 million, cela prendrait peut-être 30 minutes si l'échelle évoluait de manière linéaire, mais cela ne semble pas être le cas.
Je télécharge un sous-ensemble purifié de la table de données pour référence avec l'amélioration du script suggérée enregistrée dans la table de données.La table nettoyée ne contenait qu'un seul LotID, mais ce n'est généralement pas le cas et sert uniquement à minimiser la taille totale du fichier à télécharger.
Voici la version actuelle du script que j'essaie d'exécuter sur la table :
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 );
Encore une fois, merci beaucoup pour l'aide !
Re : Problème avec le script pour supprimer les mesures redondantes spécifiques à certaines conditionsBonjour et merci!
J'exécute maintenant le script sur ma table de données ; Je pense que vous aviez certainement raison de parcourir les lignes d'une table dont la ligne est activement considérée comme supprimée, ce qui perturbait probablement la logique de la boucle.
J'exécute maintenant le code sur ma table de données et je ferai un rapport.Je vais également essayer de voir si je peux nettoyer un extrait de ma table de données pour me permettre de l'inclure dans cet article.Merci beaucoup pour votre aide!
Re : Problème avec le script pour supprimer les mesures redondantes spécifiques à certaines conditionsJe pense que vous rencontrez un problème dans lequel vous parcourez une table de données à l'aide d'un For Each Row, et vous continuez à modifier la table que vous parcourez en supprimant des lignes, et la boucle devient confuse.
Voici un morceau de code non testé qui, je pense, éliminera le problème et devrait fonctionner assez efficacement.
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 );
Je n'avais pas d'exemple de table de données avec lequel travailler, le code n'est donc pas testé, mais l'approche devrait vous permettre de résoudre tous les problèmes et de le faire fonctionner.