Estrazione di parole da una riga come nome di colonna e i numeri corrispondenti come valori nella colonnaHo una colonna denominata "Fault" - dove ho i codici di errore estratti da vari dispositivi. Di seguito è riportato uno dei codici di errore di un determinato giorno.
"inverter Inverter 20 al di sotto del limite: 0,96 Kilowatt/inverter (58,9 % di 1,63 Kilowatt) al 30/11/2019 7:30:00 AM (dom az: 123,4 el: 3,7) Durata: 4,00 ore inverter Inverter 23 al di sotto del limite: 0,95 Kilowatt/inverter (57,9 % di 1,63 Kilowatt) al 30/11/2019 7:30:00 AM (dom az: 123,4 el: 3,7) Durata: 3,50 ore"
L'obiettivo è eseguire un'analisi per tabulare gli inverter difettosi per data e le relative prestazioni e durata cumulative; successivamente utilizzare gli altri valori per diagnosticare il guasto.
Ho bisogno di estrarre i dettagli come segue nel formato ---- Nome colonna: Valore
Invertitore: 20
Sotto il limite (kW/Inverter): 0,96
% del massimo: 58,9%
Data 30/11/2019
Orario: 7:30:00
Sun Az: 123,4
Altitudine: 3,7
Durata (ore): 4
Se c'è un secondo inverter che ha anche un codice di errore allora (vedi seconda riga nel codice di errore sopra)
Invertitore: 23
Sotto il limite (kW/Inverter): 0,95
% del massimo: 57,9%
Data 30/11/2019
Orario: 7:30:00
Sun Az: 123,4
Altitudine: 3,7
Durata (ore): 3.50
A volte potrebbero esserci 5 o 10 inverter (su 70) che potrebbero dare codici simili in una sola riga.
Puoi farmi sapere come farlo. È solo tramite JSL? o posso usare formule? Ad ogni modo, ho bisogno di aiuto.
Modellazione statistica avanzataAutomazione e scriptingConsumatori e ricerche di mercatoPersonalizzazione di massaQualità e ingegneria di processoOggetto: Estrazione di parole da una riga come nome di colonna e i numeri corrispondenti come valori nella colonnaCiao SunnyR,
So che questo è un vecchio post, ma ho trovato il problema interessante e volevo condividere un'idea che a volte utilizzo in situazioni simili alla tua. È molto potente (e semplice) SE i dati sono ben strutturati e non troppo complessi, i tuoi si qualificano.
NOTA: questa particolare soluzione presuppone che i tuoi registri si trovino attualmente in una singola colonna di dati, che è l'unica colonna di dati nella tabella. Come hai detto, righe diverse possono contenere numeri diversi di registri dell'inverter.
Ho notato che la parola "ore" compare solo alla fine del registro di ogni inverter, quindi possiamo interrompere i record del registro in questo modo e impilare i dati. Una volta fatto ciò, suddivideremo il testo per mantenere i numeri. È importante che tutti i registri abbiano lo stesso testo e le stesse misure, sempre nello stesso ordine, quindi questi saranno allineati in colonne quando spezziamo il testo.
Convertiremo tutte le colonne in valori numerici, il che rende i dati non numerici ovvi, ovvero mancanti. Elimineremo i dati non numerici, rinomineremo le colonne e avremo finito.
Ho allegato una tabella con uno script di tabella in modo da poter vedere come funziona.
Names Default To Here( 1 );
dt = :log << get data table; // for use within a table script. otherwise, use dt = current data table();
// can break up the logs at "hours". Replace with ~ or some other unused character to delimit.
For( i = 1, i <= N Row( dt ), i++,
dt:log[i] = Substitute( dt:log[i], "hours", "~" )
);
//split the logs using this delimiter
dt << Text to Columns( delimiters( "~" ), columns( :log ) );
// some logs had more inverters than others, so the stack my have empty data in some rows. Delete them.
dt2 = dt << stack( columns( (dt << get column names)[2 :: N Col( dt )] ) );
dt2 << delete rows(dt2 << get rows where (:data == ""));
//using parens and spaces as delimiters, break up each log
dt2 << text to columns( delimiters( " ()" ), columns( :data ) );
//deal with date and time. They're always in the same columns, making this easier
dt2 << New Column( "date", formula( Informat( :data 14 ) ) );
dt2 << New Column( "time", formula( Informat( :data 15 || " " || :data 16 ) ) );
dt2:date << Delete Formula;
dt2:time << Delete Formula;
dt2 << delete columns( {"data 14", "data 15"} ); //else these persist later, as they are numeric
//Remove non-numeric columns by changing all columns to numeric and removing those containing only missing data.
//Proceed "backward" as deletions change indices.
For( i = N Col( dt2 ), i >= 1, i--,
Column( dt2, i ) << set data type( numeric );
If( N Row( Loc( dt2:i << get values ) ) == 0, dt2 << delete columns( i ) );
);
//rename columns and reformat date and time.
colNames = Words( "Inverter,Below Limit(kw/inverter),% of max,Max,Sun Az,Elevation,Duration", "," );
For( i = 1, i <= N Items( colNames ), i++, Column( dt2, i ) << set name( colNames[i] ) );
dt2:date << Format( "m/d/y" );
dt2:time << Format( "h:m:s" );Oggetto: Estrazione di parole da una riga come nome di colonna e i numeri corrispondenti come valori nella colonnaSorprendente! Funziona. Grazie per la pazienza dimostrata nello scrivere questo lungo codice per soddisfare la mia richiesta. Sto cercando di implementare questo ad altri codici di avviso che ho. Grazie mille. Mi ha salvato eoni.
Oggetto: Estrazione di parole da una riga come nome di colonna e i numeri corrispondenti come valori nella colonnaHo avuto un po' di tempo libero...non c'è molto altro da fare con il Covid-19 ancora in giro, quindi ho scritto un po' di JSL che dovrebbe darti un buon inizio con la lettura dei tuoi dati
Names Default To Here( 1 );
dt = Open(
"Path to the data file",
columns( New Column( "c000001", Character, "Nominal" ) ),
Import Settings(
End Of Line( CRLF, CR, LF ),
End Of Field( CSV( 0 ) ),
Strip Quotes( 1 ),
Use Apostrophe as Quotation Mark( 0 ),
Use Regional Settings( 0 ),
Scan Whole File( 1 ),
Treat empty columns as numeric( 0 ),
CompressNumericColumns( 0 ),
CompressCharacterColumns( 0 ),
CompressAllowListCheck( 0 ),
Labels( 0 ),
Column Names Start( 1 ),
Data Starts( 1 ),
Lines To Read( "All" ),
Year Rule( "20xx" )
)
);
// Create the new output data table
dtLong = New Table( "Long Data",
New Column( "Label", character ),
New Column( "Value", character ),
New Column( "Line" ),
New Column( "Instance" )
);
// A function that returns the next word in the line and
// then removes the word from the front of the target line
getWord = Function( {},
theWord = Trim( Word( 1, target, " " ) );
target = Trim( Substr( target, Length( theWord ) + 1 ) );
theWord;
);
// Loop through all rows in the input data table
For( i = 1, i <= N Rows( dt ), i++,
instance = 0;
target = Column( dt, 1 )[i];
While( Word( 1, target, " " ) != "",
dtLong << add rows( 1 );
dtLong:line[N Rows( dtLong )] = i;
theWord = getWord();
Match( theWord,
"inverter",
instance++;
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:Label[N Rows( dtLong )] = theWord;
theWord = getWord();
theWord = getword();
dtLong:value[N Rows( dtLong )] = theWord;,
"below",
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:Label[N Rows( dtLong )] = theWord || " limit (KW/Inverter)";
theWord = getWord();
theWord = getWord();
dtLong:value[N Rows( dtLong )] = theWord;
// Get the % of Max
dtLong << Add Rows( 1 );
dtLong:line[N Rows( dtLong )] = i;
dtLong:Instance[N Rows( dtLong )] = instance;
theWord = getWord();
theWord = getWord();
dtLong:Label[N Rows( dtLong )] = "% of Max";
dtLong:value[N Rows( dtLong )] = Substr( theWord, 2 );
// Skip forward to the Date
For( k = 1, k <= 5, k++,
theWord = getWord()
);
// Get the Date
dtLong << add rows( 1 );
theWord = getWord();
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:line[N Rows( dtLong )] = i;
dtLong:Label[N Rows( dtLong )] = "Date";
dtLong:value[N Rows( dtLong )] = theWord;
// Get the Time
dtLong << add rows( 1 );
theWord = getWord();
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:line[N Rows( dtLong )] = i;
dtLong:Label[N Rows( dtLong )] = "Time";
dtLong:value[N Rows( dtLong )] = theWord || getWord();
// Get the Sun Az
dtLong << add rows( 1 );
theWord = getWord();
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:line[N Rows( dtLong )] = i;
dtLong:Label[N Rows( dtLong )] = Substr( theWord, 2 ) || " " || getWord();
dtLong:value[N Rows( dtLong )] = getWord();
// Get the Elevation
dtLong << add rows( 1 );
theWord = getWord();
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:line[N Rows( dtLong )] = i;
dtLong:Label[N Rows( dtLong )] = "Elevation";
dtLong:value[N Rows( dtLong )] = Word( -1, getWord(), ")" );,
"Duration:",
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:Label[N Rows( dtLong )] = theWord || " (hrs)";
dtLong:value[N Rows( dtLong )] = getWord();
theWord = getWord();
)
;
);
);Oggetto: Estrazione di parole da una riga come nome di colonna e i numeri corrispondenti come valori nella colonnaJim
Grazie per il tuo suggerimento. Cercherò. Dato che sono nuovo nello scripting, esaminerò esempi per capirlo.
Oggetto: Estrazione di parole da una riga come nome di colonna e i numeri corrispondenti come valori nella colonnaHo dovuto gestire dati come questo molte volte.L'approccio che penso debba essere adottato è leggere tutti i dati dal file di input in una tabella di dati JMP, in cui ogni riga completa viene letta in una singola colonna.Ti ritroverai con una tabella di dati con una colonna e il numero di righe uguale al numero di righe nella tabella di dati di input.
Successivamente, crei una nuova tabella con 3 colonne, Etichetta, Valore e Linea.Quindi, utilizzando JSL che esegue la scansione del contenuto di ciascuna riga in una colonna, si crea una nuova riga nella nuova tabella e si popola l'etichetta (ad esempio inverter, sotto il limite (KW/inverter) ecc.), il valore (ad esempio 20 , 0.96, ecc.) e Line, che sarebbe solo il numero di riga corrente.....Row().Potrebbe anche essere necessaria una colonna di output aggiuntiva basata sul fatto che questo sia il 1° inverter sulla linea o il 2° inverter.....ecc.
Questo può essere fatto usando una funzione While() in combinazione con la funzione Word() che cerca ":" come delimitatore.Le parole con numero dispari sarebbero le Etichette, quelle con numero pari saranno i Valori.
Una volta creata questa nuova tabella, puoi spostarti facilmente in una riga per inverter, utilizzando Tables=>Split.
Oggetto: Estrazione di parole da una riga come nome di colonna e i numeri corrispondenti come valori nella colonnaDave,
Sì, potrei se ho solo 1 o 2 inverter difettosi, ma se ad esempio ho 23 codici di errore in una singola riga per una singola data, allora devo creare così tante colonne individualmente e poi scrivere formule per ciascuna delle 23 inverter. Puoi chiarire se capisco la tua soluzione.Ho anche aggiunto un'altra riga che riassume l'obiettivo dell'analisi dopo l'estrazione.
Oggetto: Estrazione di parole da una riga come nome di colonna e i numeri corrispondenti come valori nella colonnaDovresti essere in grado di fare molti progressi su questo usando l'editor di formule: dai un'occhiata alla funzione WORD