JSL 表導入 - 當所需行號可變時選擇正確的行作為標題我有一個腳本,它使用輸入列表從目錄中提取文件。文件格式很不尋常,因此需要進行一些操作,並且每個文件約為 60Mb,因此導入可能需要比我想要的更多時間。我的問題是,大多數文件在第 15 行都有所需的標題行,但大約 10% 的文件的標題可能位於第 10-14 行的任何位置,並且在我打開文件之前無法知道。
我當前的解決方案是讓腳本打開前 20 行,搜索包含標題的行並將該行號分配給一個變量,關閉該 dt,然後重新打開,但使用該變量作為標題,使用變量 + 1 作為第一行。它有效,但這意味著我要打開這些文件兩次,儘管其中一次只是有限的預覽。
1)有更好的方法嗎?
2)當我問時,有沒有一種方法可以導入表,但僅根據名稱導入我想要的列?我的文件大約有 1000 列,而我只需要其中大約 15 列。
回复:JSL 表導入 - 當所需行號可變時選擇正確的行作為標題我想你是對的;您可能需要使用 parse() 將字符串轉換為表達式。
您可以採用另一種方法來避免使用字符串並直接操作表達式:
// testing data (I modified your end of field with a tab, below)
filelist = {"$sample_data\..\Import Data\bigclass.txt"};
x = 1;
// build an expression with a placeholder COLUMNSEXPR
openstmt = Expr(
Open(
FileList[x],
COLUMNSEXPR, // << placeholder for columns(...)
Import Settings( End Of Line( CRLF, CR, LF ), End Of Field( tab, CSV( 0 ) ),
Strip Quotes( 1 ), Column Names Start( 1 ), Data Starts( 1 ) )
)
);
// if you run the openstmt function now, it will import all the columns
//
// eval(openstmt);
// build a list using {} to make it easy to manipulate
COLUMNSLIST = {};
// insert the column you want to keep
Insert Into( COLUMNSLIST, Expr( New Column( "Col1", Character, "Nominal" ) ) );
// insert 5 omit columns...
For( i = 1, i < 5, i += 1,
Insert Into( COLUMNSLIST, Expr( Omitted Column( . ) ) )
);
// COLUMNSLIST looks like this:
//{New Column( "Col1", Character, "Nominal" ), Omitted Column( . ),
//Omitted Column( . ), Omitted Column( . ), Omitted Column( . )}
// convert the {...} to columns(...)
Substitute Into( COLUMNSLIST, Expr( {} ), Expr( columns ) );
//show(nameexpr(COLUMNSLIST)); shows this:
//columns(New Column("Col1", Character, "Nominal"),
//Omitted Column(.), Omitted Column(.),
//Omitted Column(.), Omitted Column(.))
//
// if you leave out the nameexpr() it will (try to) evaluate rather than
// retrieving the expression for display. columns() is not a function in
// JSL, so evaluating makes an error message.
// nameexpr(openstmt) still show COLUMNSEXPR. replace it:
Substitute Into( openstmt, Expr( COLUMNSEXPR ), Name Expr( COLUMNSLIST ) );
// nameexpr(openstmt) is now
//Open(
// FileList[x],
// columns(
// New Column( "Col1", Character, "Nominal" ),
// Omitted Column( . ),
// Omitted Column( . ),
// Omitted Column( . ),
// Omitted Column( . )
// ),
// Import Settings(
// End Of Line( CRLF, CR, LF ),
// End Of Field( tab, CSV( 0 ) ),
// Strip Quotes( 1 ),
// Column Names Start( 1 ),
// Data Starts( 1 )
// )
//)
Eval( openstmt ); // reads just the first column of the table您還可以通過操作文本而不是表達式來執行類似的操作,然後
eval(parse( " the text you built ") )
使用您最熟悉的技術;操作表達式的速度會略有提高,但與從磁盤讀取文件相比微不足道。
請注意,上面的最終語句仍然取決於 X 的值來選擇要打開的文件,因此不需要重建表達式。
回复:JSL 表導入 - 當所需行號可變時選擇正確的行作為標題@Craige_Hales
我正在尋找一種方法來縮短導入這些 .csv 類文件的代碼。我有一個導入現在有大約 1000 列,另一個導入有大約 360 列,並且這個循環現在在名為“FileList”的列表中的數百個文件。由於上述原因,我只想導入第 1 列。我當前的代碼如下所示:
For( x = 1, x <= N Items( FileList ), x++,
dt = Open(
FileList[x],
eval(columns(
New Column( "Col1", Character, "Nominal" ),
Omitted Column( . ),
Omitted Column( . ),
Omitted Column( . ), <FONT color="#FF0000">(repeated 400 times!)</FONT>
),
Import Settings(
End Of Line( CRLF, CR, LF ),
End Of Field( Spaces, Space, CSV( 0 ) ),
Strip Quotes( 1 ),
Column Names Start( 1 ),
Data Starts( 1 ),
),
//invisible
);但我試圖弄清楚如何使用 eval() 類型表達式,但我做得不正確。我已經在不同的地方嘗試過 eval() 表達式,但似乎無法得到它。我是 eval() 新手。我想也許我的問題是我的變量“Omit”最終是一個字符串,但用引號引起來?
<FONT color="#339966"> Omit</FONT> = repeat("Omitted Column( . ),",400)||"Omitted Column( . )";
For( x = 1, x <= N Items( FileList ), x++,
dt = Open(
FileList[x],
<FONT color="#FF0000">eval(</FONT>columns(
New Column( "Col1", Character, "Nominal" ),
<FONT color="#339966">Omit</FONT><FONT color="#FF0000">);</FONT>
),
Import Settings(
End Of Line( CRLF, CR, LF ),
End Of Field( Spaces, Space, CSV( 0 ) ),
Strip Quotes( 1 ),
Column Names Start( 1 ),
Data Starts( 1 ),
),
);
回复:JSL 表導入 - 當所需行號可變時選擇正確的行作為標題很高興這會有所幫助,似乎是一個值得的願望清單項目。
回复:JSL 表導入 - 當所需行號可變時選擇正確的行作為標題謝謝克雷格。 對於初始導入以獲取帶有列標題的行,我使用了您的建議,並使用了第2 至1000 列的省略列,因此我只導入包含20 行的第1 列,獲取我需要的內容,然後將其關閉。 然後,我重新打開該文件,但使用循環第一部分中的信息來正確選擇列標題行。
我確實希望有一種更好的方法來為循環的第二部分導入特定列。 在我的情況下,原始輸入文件中的列可能會隨著時間的推移在我不知情的情況下更改順序和數量。 如果 JMP 能夠僅通過名稱指定要導入的列,那就太好了。回复:JSL 表導入 - 當所需行號可變時選擇正確的行作為標題1)我認為兩次導入可能是最簡單的方法並且可以做得更快......
2)您需要指定的不僅僅是要導入的列,但加速是值得的......
use the text import wizard to mark the unwanted columnsuse the text import wizard to mark the unwanted columns使用文本導入嚮導標記不需要的列
Grab the source script, it has the JSL to omit columnsGrab the source script, it has the JSL to omit columns獲取源腳本,它具有省略列的 JSL
(對於 1000 個省略的列,編輯 JSL 可能比使用 GUI 排除更容易。)
現在,您可以調整源腳本。 下面是前 100 行。 它很快,因為 (1) 有關列的所有內容都已指定,並且 (2) 在 100 行後停止。 對於此數據,我應該指定 Labels(0) 和 DataStarts(1)。
Open(
"f:\logOriginalAntenna.txt",// 100MB file takes about 2 seconds to load 100 lines
columns(
Omitted Column( . ),// use the import wizard to
Omitted Column( . ),// get a source script with
Omitted Column( . ),// omitted columns
New Column( "c000004",
Numeric,
"Continuous",
Format( "yyyy-mm-ddThh:mm:ss", 23, 3 ),
Input Format( "yyyy-mm-ddThh:mm:ss", 3 )
),
New Column( "c000005", Character, "Nominal" )
),
Import Settings(
End Of Line( CRLF, CR, LF ),
End Of Field( Tab, Comma, CSV( 1 ) ),
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( 1 ),
Column Names Start( 1 ),
Data Starts( 2 ),
Lines To Read( 100 ),// specify the number of rows
Year Rule( "20xx" )
)
)
如果您的文件始終具有相同的列順序,則明確指定格式(見上文)將意味著 JMP 在導入文件之前不需要研究該文件。 我認為 JMP 仍在研究全部的即使你停在 100 行,也可以文件,所以這可以大大減少處理時間。
如果文件並不總是具有相同的列數或列順序,則此方法將不起作用。 您也許可以使用單次導入來導入表、修復列名稱和數據類型、刪除不需要的行...。