Concatena più tabelle con ordine di colonne diversoSquadra,
Ho 5 file CSV ciascuno con 200 colonne (non tutti i file hanno lo stesso numero di colonne). Ogni file ha colonne in ordine diverso. Voglio scrivere uno scirpt che consentirà all'utente di selezionare tutti e 5 i file, quindi combinare tutti e 5 i file (eliminando le colonne non corrispondenti) e salvare il file CSV combinato nella posizione richiesta. Voglio usare un comando simile a (data = Open(Pick File("Scegli il file", x)), x è la directory), per scegliere i file.
Grazie
Ri: Concatenare più tabelle con ordine di colonne diversoGrazie @txnelson
Sei sempre di grande aiuto.Ri: Concatenare più tabelle con ordine di colonne diversoEcco una rielaborazione dello script, selezionando tutti i file da concatenare in un'unica selezione e quindi eseguendo un piccolo script per metterli insieme, mantenendo solo le colonne che trovano una corrispondenza. L'ho costruito secondo le tue specifiche, tuttavia potrebbe essere facilmente modificato per consentire la concatenazione di un numero qualsiasi di file
Names Default To Here( 1 );
inputDirectory = "C:\";
// Select the files to be read in......this can be any number of files
filePath = Pick File(
"Choose the File to be Concatenated to:",
inputDirectory,
{"CSV Files|csv;", "All Files|*"},
1,
0,
""
);
// Open the first file
dtMain = Open( filePath, invisible );
files = Pick File(
"Choose the Additional 4 Files to Read In:",
inputDirectory,
{"CSV Files|csv;", "All Files|*"},
1,
0,
"",
multiple
);
// Validate that files have been read in
If( Try( N Items( files ), 0 ) == 4,
Dialog( "Incorrect number of files were read in."
"Only 4 additional files can be read in");
Throw( "Incorrect number of files were read in" );
);
// Read in the remaining files and process them
For( i = 2, i <= N Items( Files ), i++,
Try( dtConCat = Open( Files[i], invisible ) );
mainColList = dtMain << Get Column Names( string );
conCatColList = dtConCat << Get Column Names( string );
// Delete the columns in the dtConCat table that do not exist in the dtMain table
delList = {};
For( k = 1, k <= N Items( conCatColList ), k++,
If( N Rows( Loc( mainColList, conCatColList[k] ) ) == 0,
Insert Into( delList, conCatColList[k] )
)
);
If( N Items( delList ) > 0,
dtConCat << delete columns( delList )
);
// Delete the columns in the dtMain table that were not found in the dtConCat table
delList = {};
For( k = 1, k <= N Items( mainColList ),
k++,
If( N Rows( Loc( conCatColList, mainColList[k] ) ) == 0,
Insert Into( delList, mainColList[k] )
)
);
If( N Items( delList ) > 0,
dtMain << delete columns( delList )
);
// If any columns still remain in the two tables, then concatenate them together
If( N Cols( dtMain ) > 0 & N Cols( dtConCat ) > 0,
dtMain = dtMain << Concatenate( dtConCat, Append to First Table )
);
// Close the no longer needed file
Close( dtConCat, nosave );
);
// Make the main file visible
dtMain << show window( 1 );
Ri: Concatenare più tabelle con ordine di colonne diverso@Rajat ,
Non capisco perché dovresti creare una nuova tabella. Farei qualcosa del genere.
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
OriginalColOrder = dt << Get Column Names("string");
dt << Reorder By Name();
SortedColOrder = dt << Get Column Names("string");
Show(OriginalColOrder);
Show(SortedColOrder); Gli elenchi forniscono sia l'ordine ordinato che l'ordine originale. Inoltre, condividi ciò che hai provato finora, così sarà più facile vedere dove sei diretto. Non riesco a capire esattamente cosa hai provato finora e dove stai fallendo. Se non riesci a condividere i tuoi dati, prova a creare alcuni dati di esempio, in modo che sia facile per tutti ricreare i problemi e aiutarti.
Ri: Concatenare più tabelle con ordine di colonne diverso@uday_guntupalli
Puoi aiutarmi a scrivere la sintassi per salvare l'ordine originale e riordinare la tabella finale con l'ordine salvato?
GrazieRi: Concatenare più tabelle con ordine di colonne diverso@Rajat ,
dt << Reorder By Name();
Ri: Concatenare più tabelle con ordine di colonne diversoGrazie @uday_guntupalli
Se possiamo riordinare le colonne e farle avere lo stesso ordine. Successivamente concateneremo tutte le tabelle.
Puoi aiutarmi a scrivere la sintassi per riordinare le colonne di tutte le tabelle in base alla prima tabella, quindi utilizzeremo il comando concatena in un ciclo. Se non è possibile, possiamo salvare l'ordine originale delle colonne della prima tabella, quindi riordinare tutte le tabelle con il loro nome e quindi concatenarle in un ciclo. Infine riordineremo la tabella finale in base all'ordine delle colonne salvato in precedenza.
@Craige_Hales @txnelson avete qualche soluzione per questo problema?
Grazie. Apprezzo il tuo aiuto.Ri: Concatenare più tabelle con ordine di colonne diverso@Rajat ,
ThisListAsAA = Associative Array(ThisList);
ThisListAsAAKeys =ThisListAsAA << Get Keys;
If(i == 1,
CommonItems = ThisListAsAAKeys;
,
// else
CommonItems << Intersect(ThisListAsAAKeys);
);
Un array associativo ha una relazione o mappatura uno a uno. Quindi, una volta costruito un array associativo, la seconda riga tenta di estrarre le chiavi univoche nella mappa dell'array associativo. Per quanto riguarda il blocco If, pensa alla teoria degli insiemi, quando i = 1, stiamo assegnando al risultato le chiavi univoche dell'array associativo 1. Da lì in poi, lo intersechiamo ripetutamente con altri array associativi per arrivare finalmente a un elenco che avrà solo elementi comuni a tutti gli array associativi.
Select( :name, :age, :sex, :height, :weight ),
By Row Number
Questo era un errore di battitura dal mio esempio. Select(CommonItems) sarebbe appropriato.
Non so se Concatenate funzionerà, puoi provarlo
Ri: Concatenare più tabelle con ordine di colonne diverso@uday_guntupalli
Grazie per il tuo ottimo aiuto.
Ho pochi commenti
- Tutte le tabelle hanno un numero diverso di righe.
- Voglio concatenare (il numero di righe nella tabella finale sarà la somma del numero di righe della singola tabella) le tabelle per non unirle. Il ciclo concatenato funzionerà allo stesso modo?
Inoltre, potresti aiutarmi a capire i seguenti comandi.
- In loop per trovare nomi di colonne comuni. Potete per favore spiegare le seguenti righe.
ThisListAsAA <SPAN class="token operator">=</SPAN> <SPAN class="token function">Associative Array</SPAN><SPAN class="token punctuation">(</SPAN>ThisList<SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">;</SPAN>
ThisListAsAAKeys <SPAN class="token operator">=</SPAN>ThisListAsAA <SPAN class="token operator"><</SPAN><SPAN class="token operator"><</SPAN><SPAN class="token messages"> Get Keys</SPAN><SPAN class="token punctuation">;</SPAN>
<SPAN class="token function">If</SPAN><SPAN class="token punctuation">(</SPAN>i <SPAN class="token operator">==</SPAN> <SPAN class="token number">1</SPAN><SPAN class="token punctuation">,</SPAN>
CommonItems <SPAN class="token operator">=</SPAN> ThisListAsAAKeys<SPAN class="token punctuation">;</SPAN>
<SPAN class="token punctuation">,</SPAN>
<SPAN class="token comment">// else </SPAN>
CommonItems <SPAN class="token operator"><</SPAN><SPAN class="token operator"><</SPAN><SPAN class="token messages"> Intersect</SPAN><SPAN class="token punctuation">(</SPAN>ThisListAsAAKeys<SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">;</SPAN>
<SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">;</SPAN>
Per quanto ho capito in " Questa lista è AA " , " Questa lista " verrà memorizzato come array associativo. Per favore aiutaci a capire le due righe successive. - In loop per unire le tabelle, puoi spiegare le righe seguenti.
Select<SPAN class="token punctuation">(</SPAN> <SPAN class="token punctuation">:</SPAN>name<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>age<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>sex<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>height<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>weight <SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">,</SPAN>
By Row Number
Non ci sono colonne con nomi di colonna: nome, : età ecc. E manualmente non possiamo scrivere per selezionare le colonne poiché il numero è enorme. Inoltre non possiamo unirci per numero di riga poiché il numero di righe è diverso e vogliamo concatenare la tabella senza unirla.
Grazie
Ri: Concatenare più tabelle con ordine di colonne diverso@Rajat ,
Sto presupponendo (non so quanto sia valido) che tu abbia lo stesso numero di righe.
// Define Your Directory and a list to hold File Paths
MyDirectory = "C:\" ;
nFiles = 5;
MyFilePaths = {};
ColNamesListOfList = {};
OpenDts = {};
// Test if Directory exists and get all file paths
Try( If(Directory Exists(MyDirectory),
for(i = 1 , i <= nFiles, i ++,
FilePath = Pick File( "Select File", MyDirectory);
Insert Into(MyFilePaths,FilePath);
);
,
// else
Throw()
),
"Unable to Open File";
);
// Get List of All Column Names
for(i = 1, i <= nFiles, i++,
OpenDts[i] = Open(MyDirectory || "\" || FilePath[i],"Invisible");
ColNames = OpenDts[i] << Get Column Names("String");
Insert Into(ColNamesListOfList,ColNames);
);
// Find Common Column Names
for(i = 1, i <= nFiles, i++,
ThisList = ColNamesListOfList[i];
ThisListAsAA = Associative Array(ThisList);
ThisListAsAAKeys =ThisListAsAA << Get Keys;
If(i == 1,
CommonItems = ThisListAsAAKeys;
,
// else
CommonItems << Intersect(ThisListAsAAKeys);
);
);
// Concatenate
for(i = 1, i <= nFiles, i++,
If(i == 1,
dt_Results = OpenDts[i];
,
dt_Results << Join(With( OpenDts[i]),
Merge Same Name Columns,
Select( :name, :age, :sex, :height, :weight ),
By Row Number // assuming that the tables have the same number of rows
);
);
); Ri: Concatenare più tabelle con ordine di colonne diversoGrazie Uday. Voglio concatenare le colonne comuni.Ri: Concatenare più tabelle con ordine di colonne diverso@Rajat ,
Considerando il problema che hai descritto, suddividiamolo in più passaggi.
Passaggio 1: selezionare i file desiderati utilizzando Pick File ()
),
"Unable to Open File";
); // Define Your Directory and a list to hold File Paths
MyDirectory = "C:\" ;
nFiles = 5;
MyFilePaths = {};
OpenDts = {};
// Test if Directory exists and get all file paths
Try( If(Directory Exists(MyDirectory),
for(i = 1 , i <= nFiles, i ++,
FilePath = Pick File( "Select File", MyDirectory);
Insert Into(MyFilePaths,FilePath);
); <BR /> , <BR /> // else<BR /> Throw()<BR />
Passaggio 2: scorrere i file, aprire e concatenare colonne comuni
Ecco, ho una domanda per te. Esiste un elenco di colonne che ti aspetti nella tabella finale (o) sono solo le colonne comuni a tutti e 5 i file CSV?