從行中提取單詞作為列名,並將其相應的數字作為值提取到列中我有一個名為“故障”的列,其中有從各種設備中提取的故障代碼。 下面給出了某一天的故障代碼之一。
“逆變器 逆變器 20 低於限制:0.96 千瓦/逆變器(1.63 千瓦的 58.9 %),2019 年 11 月 30 日上午 7:30:00(太陽 az:123.4 el:3.7) 持續時間:4.00 小時 逆變器 23 低於限制:0.95千瓦/逆變器(1.63 千瓦的 57.9 %),2019 年 11 月 30 日上午 7:30:00(太陽 az:123.4 el:3.7)持續時間:3.50 小時"
目標是執行分析,按日期及其累積性能和持續時間列出故障逆變器;稍後使用其他值來診斷故障。
我需要按以下格式提取詳細信息:----列名:值
逆變器:20個
低於限制(kW/逆變器):0.96
最大百分比:58.9%
日期 11/30/2019
時間 : 上午 7:30:00
太陽 AZ : 123.4
海拔:3.7
持續時間(小時):4
如果有第二個逆變器也有故障代碼(請參閱上面故障代碼中的第二行)
逆變器:23
低於限制(kW/逆變器):0.95
最大百分比:57.9%
日期 11/30/2019
時間 : 上午 7:30:00
太陽 AZ : 123.4
海拔:3.7
持續時間(小時):3.50
有時可能有 5 或 10 個逆變器(總共 70 個),它們可以在一行中給出類似的代碼。
你能讓我知道如何完成這件事嗎? 只能通過JSL嗎?或者我可以使用公式嗎? 不管怎樣——我需要一些幫助。
高級統計建模自動化和腳本編寫消費者和市場研究大規模定制質量和工藝工程回复:從行中提取單詞作為列名稱,並將其相應的數字作為值提取到列中嗨桑尼R,
我知道這是一篇舊帖子,但我發現這個問題很有趣,並且想分享我有時在與您類似的情況下使用的想法。 如果數據結構良好且不太複雜(您的數據符合條件),那麼它就非常強大(而且簡單)。
注意:此特定解決方案假設您的日誌當前位於單數據列中,這是表中唯一的數據列。 正如您所提到的,不同的行可能包含不同數量的逆變器日誌。
我注意到“小時”一詞僅出現在每個逆變器日誌的末尾,因此我們可以通過這種方式打破日誌記錄並堆疊數據。 完成後,我們將分解文本以保留數字。 重要的是,所有日誌都具有相同的文本和測量值,並且始終以相同的順序 - 因此當我們分解文本時,這些將在列中對齊。
我們將所有列轉換為數字,這使得非數字數據變得明顯,即缺失。 我們將刪除非數字數據,重命名列,然後就完成了。
我附上了一個帶有表格腳本的表格,以便您可以了解其工作原理。
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" );回复:從行中提取單詞作為列名稱,並將其相應的數字作為值提取到列中驚人的! 它有效。感謝您耐心編寫這段長代碼來完成我的請求。 我正在嘗試將其實現到我擁有的其他警報代碼中。非常感謝。它為我節省了很多時間。
回复:從行中提取單詞作為列名稱,並將其相應的數字作為值提取到列中我有一些空閒時間......沒有太多其他事情可做,因為 Covid-19 仍然存在,所以我寫了一些 JSL,這應該可以為您讀取數據提供一個良好的開端
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();
)
;
);
);回复:從行中提取單詞作為列名稱,並將其相應的數字作為值提取到列中吉姆
謝謝你的建議。 我會嘗試。 由於我是腳本編寫新手,我將通過示例來弄清楚。
回复:從行中提取單詞作為列名稱,並將其相應的數字作為值提取到列中我曾多次不得不處理這樣的數據。我認為必須採取的方法是將輸入文件中的所有數據讀入 JMP 數據表,其中每個完整行都讀入單個列。您最終將得到一個包含一列的數據表,行數等於輸入數據表中的行數。
接下來,您創建一個包含 3 列的新表:標籤、值和行。然後,使用 JSL 掃描一列中每一行的內容,在新表中創建一個新行,並填充標籤(即逆變器、低於限制(KW/逆變器)等)、值(即 20) 、0.96 等)和 Line,它只是當前行號.....Row()。可能還必須有一個額外的輸出列,該輸出列將基於這是線路上的第一個逆變器或第二個逆變器......等等。
這可以使用 While() 函數結合 Word() 函數掃描“:”作為分隔符來完成。奇數編號的單詞將是標籤,偶數編號的單詞將是值。
創建此新表後,您可以使用“表”=>“拆分”輕鬆移至每個逆變器一行。
回复:從行中提取單詞作為列名稱,並將其相應的數字作為值提取到列中戴夫,
是的,如果我只有 1 或 2 個有故障的逆變器,我可以,但是,例如,如果我在單個日期的一行中有 23 個故障代碼,那麼我需要單獨創建這麼多列,然後為每個故障編寫公式23個逆變器。 您能否澄清一下我是否理解您的解決方案。我還添加了另一行,總結了提取後分析的目標。
回复:從行中提取單詞作為列名稱,並將其相應的數字作為值提取到列中使用公式編輯器您應該能夠在這方面取得很大進展 - 看看 WORD 函數