Importation de table JSL - Sélection de la ligne correcte comme en-tête lorsque le numéro de ligne souhaité est variableJ'ai un script qui utilise une liste d'entrée pour extraire des fichiers d'un répertoire.Le format de fichier est inhabituel, cela nécessite donc quelques manipulations et chaque fichier fait de l'ordre de 60 Mo, donc les importations peuvent prendre plus de temps que je ne le souhaiterais.Mon problème est que la plupart des fichiers ont la ligne d'en-tête souhaitée sur la ligne 15, mais environ 10 % des fichiers ont un en-tête qui peut se trouver n'importe où entre les lignes 10 et 14 et il n'y a aucun moyen de le savoir jusqu'à ce que j'ouvre le fichier.
Ma solution actuelle consiste à ce que le script ouvre les 20 premières lignes, recherche la ligne qui contient les en-têtes et attribue ce numéro de ligne à une variable, ferme ce dt, puis rouvre mais en utilisant la variable comme en-tête et la variable + 1 comme Première ligne.Cela fonctionne mais cela signifie que j'ouvre ces fichiers deux fois, même si l'un d'entre eux n'est qu'un aperçu limité.
1) Existe-t-il une meilleure façon de procéder ?
2) Et pendant que je demande, existe-t-il un moyen d'importer une table mais d'importer uniquement les colonnes que je souhaite, en fonction de leur nom ?Mes fichiers comportent environ 1 000 colonnes et je n’en ai besoin que d’une quinzaine environ.
Re: Importation de table JSL - Sélection de la ligne correcte comme en-tête lorsque le numéro de ligne souhaité est variableJe pense que tu as raison; vous devrez peut-être utiliser parse() pour convertir la chaîne en expression.
Voici une autre approche que vous pouvez adopter pour éviter les chaînes et manipuler les expressions directement :
// 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 tableVous pouvez également faire quelque chose de similaire en manipulant du texte plutôt que des expressions, puis
eval(parse( " the text you built ") )
Utilisez la technique avec laquelle vous êtes le plus à l’aise ; il y aura une légère amélioration de la vitesse de manipulation des expressions, mais insignifiante par rapport à la lecture d'un fichier à partir du disque.
Notez que l'instruction finale ci-dessus dépend toujours de la valeur de X pour choisir un fichier à ouvrir, il n'est donc pas nécessaire de reconstruire l'expression.
Re: Importation de table JSL - Sélection de la ligne correcte comme en-tête lorsque le numéro de ligne souhaité est variable@Craige_Hales
Je cherche un moyen de raccourcir le code pour l'importation de ces fichiers de type .csv.J'ai une importation qui compte maintenant environ 1 000 colonnes et une autre avec environ 360, et cela parcourt des centaines de fichiers maintenant dans une liste appelée "FileList".Je souhaite uniquement importer la colonne 1 pour les raisons indiquées ci-dessus.Mon code actuel ressemble à ceci :
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
);Mais j'essayais de comprendre comment utiliser une expression de type eval() mais je ne le fais pas correctement.J'ai essayé l'expression eval() à divers endroits mais je n'arrive pas à l'obtenir.Je suis nouveau sur eval().Je pense que mon problème est peut-être que ma variable "Omit" finit par être une chaîne mais entourée de guillemets ??
<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 ),
),
);
Re: Importation de table JSL - Sélection de la ligne correcte comme en-tête lorsque le numéro de ligne souhaité est variableheureux que cela aide, cela semble être un élément de liste de souhaits digne.
Re: Importation de table JSL - Sélection de la ligne correcte comme en-tête lorsque le numéro de ligne souhaité est variableMerci Craige. Pour l'importation initiale afin d'obtenir la ligne avec les en-têtes de colonne, j'ai utilisé vos conseils et utilisé la colonne d'omission pour les colonnes 2 à 1000, donc j'importe uniquement la colonne 1 avec 20 lignes, récupérez ce dont j'ai besoin puis fermez-la. Ensuite, je rouvre le fichier mais en utilisant les informations de la première partie de la boucle pour sélectionner correctement la ligne d'en-tête de colonne.
J'aimerais qu'il y ait une meilleure façon d'importer des colonnes spécifiques pour la 2ème partie de la boucle. Dans ma situation, les colonnes de mon fichier d'entrée brut sont susceptibles de changer d'ordre et de quantité au fil du temps sans que je le sache. Ce serait cool si JMP avait la possibilité de spécifier par nom uniquement les colonnes que vous souhaitez importer.Re: Importation de table JSL - Sélection de la ligne correcte comme en-tête lorsque le numéro de ligne souhaité est variable1) Je pense que deux importations sont probablement le moyen le plus simple et peuvent être effectuées plus rapidement...
2) Vous devrez spécifier plus que les colonnes à importer, mais l'accélération en vaudra la peine...
use the text import wizard to mark the unwanted columnsuse the text import wizard to mark the unwanted columnsutilisez l'assistant d'importation de texte pour marquer les colonnes indésirables
Grab the source script, it has the JSL to omit columnsGrab the source script, it has the JSL to omit columnsRécupérez le script source, il a le JSL pour omettre les colonnes
(pour 1 000 colonnes omises, il peut être plus facile de modifier le JSL que de l'exclure avec l'interface graphique.)
Maintenant, vous pouvez modifier le script source. Ci-dessous, il lit les 100 premières lignes. C'est rapide car (1) tout ce qui concerne les colonnes est spécifié et (2) cela s'arrête après 100 lignes. Pour ces données, j'aurais dû spécifier Labels(0) et 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" )
)
)
Si vos fichiers ont toujours le même ordre de colonnes, alors spécifier explicitement le format (ci-dessus) signifiera que JMP n'aura pas besoin d'étudier le fichier avant de l'importer. Je pense que JMP étudie toujours le entier fichier même si vous vous arrêtez à 100 lignes, cela pourrait donc réduire considérablement le temps de traitement.
Si les fichiers n'ont pas toujours le même nombre de colonnes ou le même ordre des colonnes, cela ne fonctionnera pas. Vous pourrez peut-être importer la table, corriger les noms de colonnes et les types de données, supprimer les lignes dont vous ne voulez pas... en utilisant une seule importation.