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 行,也可以文件,所以这可以大大减少处理时间。
如果文件并不总是具有相同的列数或列顺序,则此方法将不起作用。 您也许能够使用单次导入导入表、修复列名称和数据类型、删除不需要的行...。