Extrahieren von Wörtern aus einer Zeile – als Spaltennamen und den entsprechenden Zahlen als Werten in der SpalteIch habe eine Spalte mit dem Namen „Fehler“, in der ich Fehlercodes von verschiedenen Geräten extrahiert habe. Unten ist einer der Fehlercodes eines bestimmten Tages aufgeführt.
„Wechselrichter Wechselrichter 20 unter Grenzwert: 0,96 Kilowatt/Wechselrichter (58,9 % von 1,63 Kilowatt) am 30.11.2019 07:30:00 Uhr (Sonne Az: 123,4 EL: 3,7) Dauer: 4,00 Stunden Wechselrichter Wechselrichter 23 unter Grenzwert: 0,95 Kilowatt/Wechselrichter (57,9 % von 1,63 Kilowatt) am 30.11.2019 07:30:00 Uhr (Sonne Az: 123,4 el: 3,7) Dauer: 3,50 Stunden“
Das Ziel besteht darin, eine Analyse durchzuführen, um die fehlerhaften Wechselrichter nach Datum und ihrer kumulierten Unterleistung und Dauer tabellarisch zu erfassen. Verwenden Sie später die anderen Werte zur Diagnose des Fehlers.
Ich muss die Details wie folgt im Format ----Spaltenname: Wert extrahieren
Wechselrichter: 20
Untergrenze (kW/Wechselrichter): 0,96
% von Max: 58,9 %
Datum 30.11.2019
Zeit: 7:30:00 Uhr
Sun Az: 123,4
Höhe: 3,7
Dauer (Std.): 4
Wenn es einen zweiten Wechselrichter gibt, der ebenfalls einen Fehlercode hat, dann (siehe zweite Zeile im Fehlercode oben)
Wechselrichter: 23
Untergrenze (kW/Wechselrichter): 0,95
% von Max: 57,9 %
Datum 30.11.2019
Zeit: 7:30:00 Uhr
Sun Az: 123,4
Höhe: 3,7
Dauer (Std.): 3,50
Manchmal gibt es 5 oder 10 Wechselrichter (von 70), die ähnliche Codes in einer einzigen Zeile ausgeben können.
Können Sie mir sagen, wie ich das hinbekomme? Geht es nur über JSL? oder kann ich Formeln verwenden? So oder so – ich brauche etwas Hilfe.
Erweiterte statistische ModellierungAutomatisierung und SkripterstellungVerbraucher- und MarktforschungMassenanpassungQualitäts- und VerfahrenstechnikBetreff: Extrahieren von Wörtern aus einer Zeile – als Spaltennamen und den entsprechenden Zahlen als Werten in der SpalteHallo SunnyR,
Ich weiß, dass dies ein alter Beitrag ist, aber ich fand das Problem interessant und wollte eine Idee teilen, die ich manchmal in ähnlichen Situationen wie Ihrer verwende. Es ist sehr leistungsstark (und einfach), WENN die Daten gut strukturiert und nicht zu komplex sind – Ihre Daten sind dafür geeignet.
HINWEIS: Diese spezielle Lösung geht davon aus, dass Ihre Protokolle derzeit in einer einzigen Datenspalte liegen, die die einzige Datenspalte in der Tabelle ist. Wie Sie bereits erwähnt haben, können verschiedene Zeilen eine unterschiedliche Anzahl von Wechselrichterprotokollen enthalten.
Mir ist aufgefallen, dass das Wort „Stunden“ nur am Ende des Protokolls jedes Wechselrichters vorkommt, sodass wir auf diese Weise Protokolldatensätze aufschlüsseln und die Daten stapeln können. Sobald dies erledigt ist, unterteilen wir den Text, um die Zahlen beizubehalten. Es ist wichtig, dass alle Protokolle den gleichen Text und die gleichen Maße haben, immer in der gleichen Reihenfolge – damit diese beim Umbrechen des Textes in Spalten ausgerichtet werden.
Wir konvertieren alle Spalten in numerische Spalten, wodurch nicht-numerische Daten offensichtlich sind, d. h. fehlen. Wir löschen nicht numerische Daten, benennen die Spalten um und fertig.
Ich habe eine Tabelle mit einem Tabellenskript angehängt, damit Sie sehen können, wie das funktioniert.
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" );Betreff: Extrahieren von Wörtern aus einer Zeile – als Spaltennamen und den entsprechenden Zahlen als Werten in der SpalteToll! Es funktioniert. Vielen Dank für Ihre Geduld beim Schreiben dieses langen Codes, um meine Anfrage zu erfüllen. Ich versuche, dies auf andere Alarmcodes zu implementieren, die ich habe. Vielen Dank. Es hat mir Äonen erspart.
Betreff: Extrahieren von Wörtern aus einer Zeile – als Spaltennamen und den entsprechenden Zahlen als Werten in der SpalteIch hatte etwas Freizeit ... da Covid-19 immer noch da ist, hatte ich nicht viel anderes zu tun, also habe ich ein bisschen JSL geschrieben, das Ihnen einen guten Einstieg in das Einlesen Ihrer Daten ermöglichen sollte
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();
)
;
);
);Betreff: Extrahieren von Wörtern aus einer Zeile – als Spaltennamen und den entsprechenden Zahlen als Werten in der SpalteJim
Danke für deinen Vorschlag. Ich werde versuchen. Da ich neu in der Skripterstellung bin, werde ich Beispiele durchgehen, um es herauszufinden.
Betreff: Extrahieren von Wörtern aus einer Zeile – als Spaltennamen und den entsprechenden Zahlen als Werten in der SpalteIch musste schon oft mit solchen Daten umgehen.Der Ansatz, der meiner Meinung nach gewählt werden muss, besteht darin, alle Daten aus Ihrer Eingabedatei in eine JMP-Datentabelle einzulesen, wobei jede vollständige Zeile in eine einzelne Spalte eingelesen wird.Am Ende erhalten Sie eine Datentabelle mit einer Spalte und einer Anzahl von Zeilen, die der Anzahl der Zeilen in der Eingabedatentabelle entspricht.
Als Nächstes erstellen Sie eine neue Tabelle mit drei Spalten: Beschriftung, Wert und Zeile.Anschließend erstellt man mithilfe von JSL, das den Inhalt jeder Zeile in der einen Spalte scannt, eine neue Zeile in der neuen Tabelle und füllt die Beschriftung (z. B. Wechselrichter, Untergrenze (KW/Wechselrichter) usw.) und den Wert (z. B. 20) aus , 0,96 usw.) und die Zeile, die einfach die aktuelle Zeilennummer wäre.....Row().Möglicherweise muss auch eine zusätzliche Ausgangsspalte vorhanden sein, die darauf basiert, dass es sich um den ersten Wechselrichter in der Leitung oder den zweiten Wechselrichter usw. handelt.
Dies kann mithilfe einer While()-Funktion in Kombination mit der Word()-Funktion erfolgen, die nach „:“ als Trennzeichen sucht.Die ungeradzahligen Wörter sind die Beschriftungen, die geraden Wörter sind die Werte.
Sobald diese neue Tabelle erstellt wurde, können Sie mit „Tabellen=>Teilen“ ganz einfach zu einer Tabelle mit einer Zeile pro Wechselrichter wechseln.
Betreff: Extrahieren von Wörtern aus einer Zeile – als Spaltennamen und den entsprechenden Zahlen als Werten in der SpalteDave,
Ja, das könnte ich, wenn ich nur 1 oder 2 fehlerhafte Wechselrichter habe. Wenn ich dann aber zum Beispiel 23 Fehlercodes in einer einzigen Zeile für ein einzelnes Datum habe, muss ich so viele Spalten einzeln erstellen und dann Formeln für jeden einzelnen aufschreiben 23 Wechselrichter. Können Sie klären, ob ich Ihre Lösung verstehe?Ich habe außerdem eine weitere Zeile hinzugefügt, die das Ziel der Analyse nach der Extraktion zusammenfasst.
Betreff: Extrahieren von Wörtern aus einer Zeile – als Spaltennamen und den entsprechenden Zahlen als Werten in der SpalteMit dem Formeleditor sollten Sie hierbei große Fortschritte erzielen können – schauen Sie sich die WORD-Funktion an