Verketten Sie mehrere Tabellen mit unterschiedlicher SpaltenreihenfolgeTeam,
Ich habe 5 CSV-Dateien mit jeweils 200 Spalten (nicht jede Datei hat die gleiche Anzahl von Spalten). Jede Datei enthält Spalten in unterschiedlicher Reihenfolge. Ich möchte ein Script schreiben, das es dem Benutzer ermöglicht, alle 5 Dateien auszuwählen, dann alle 5 Dateien zu kombinieren (nicht übereinstimmende Spalten zu löschen) und die kombinierte CSV-Datei am erforderlichen Speicherort zu speichern. Ich möchte einen Befehl ähnlich wie (data = Open(Pick File("Choose the File", x)), x ist das Verzeichnis) verwenden, um die Dateien auszuwählen.
Danke
Betreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verkettenDanke @txnelson
Du bist immer eine große Hilfe.Betreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verkettenHier ist eine Überarbeitung des Skripts, bei der alle zu verkettenden Dateien in einer Auswahl ausgewählt werden und dann ein kleines Skript ausgeführt wird, um sie zusammenzufügen, wobei nur Spalten beibehalten werden, die eine Übereinstimmung finden. Ich habe es nach Ihren Vorgaben erstellt, es könnte jedoch leicht geändert werden, um die Verkettung einer beliebigen Anzahl von Dateien zu ermöglichen
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 );
Betreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verketten@Rajat ,
Ich verstehe nicht, warum Sie eine neue Tabelle erstellen müssten. Ich würde so etwas tun.
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); Die Listen bieten Ihnen sowohl die sortierte Reihenfolge als auch die ursprüngliche Reihenfolge. Bitte teilen Sie auch mit, was Sie bisher versucht haben, damit Sie leichter erkennen können, wohin Sie wollen. Ich kann nicht genau verstehen, was Sie bisher versucht haben und wo Sie scheitern. Wenn Sie Ihre Daten nicht weitergeben können, versuchen Sie, einige Beispieldaten zu erstellen, damit es für alle einfach ist, die Probleme nachzubilden und Ihnen bei der Orientierung zu helfen.
Betreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verketten@uday_guntupalli
Kann mir helfen, die Syntax zu schreiben, um die ursprüngliche Reihenfolge zu speichern und die endgültige Tabelle mit der gespeicherten Reihenfolge neu anzuordnen?
DankeBetreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verketten@Rajat ,
dt << Reorder By Name();
Betreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verkettenDanke @uday_guntupalli
Wenn wir die Spalten neu anordnen und dafür sorgen können, dass sie dieselbe Reihenfolge haben. Danach werden wir alle Tabellen verketten.
Können Sie mir helfen, eine Syntax zu schreiben, um die Spalten aller Tabellen basierend auf der ersten Tabelle neu anzuordnen? Dann verwenden wir den Befehl „concatenate“ in einer Schleife. Wenn dies nicht möglich ist, können wir die ursprüngliche Spaltenreihenfolge der ersten Tabelle speichern, dann alle Tabellen mit ihrem Namen neu anordnen und sie dann in einer Schleife verketten. Abschließend werden wir die endgültige Tabelle basierend auf der zuvor gespeicherten Spaltenreihenfolge neu anordnen.
@Craige_Hales @txnelson Haben Sie eine Lösung für dieses Problem?
Danke. Vielen Dank für Ihre Hilfe.Betreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verketten@Rajat ,
ThisListAsAA = Associative Array(ThisList);
ThisListAsAAKeys =ThisListAsAA << Get Keys;
If(i == 1,
CommonItems = ThisListAsAAKeys;
,
// else
CommonItems << Intersect(ThisListAsAAKeys);
);
Ein assoziatives Array verfügt über eine Eins-zu-Eins-Beziehung oder Zuordnung. Sobald wir also ein assoziatives Array erstellen, versucht die zweite Zeile, die eindeutigen Schlüssel in der Zuordnung des assoziativen Arrays zu extrahieren. Was den If-Block betrifft, denken Sie an die Mengenlehre: Wenn i = 1, weisen wir dem Ergebnis die eindeutigen Schlüssel des Assoziativen Arrays 1 zu. Von da an überschneiden wir es wiederholt mit anderen assoziativen Arrays, um schließlich zu einer Liste zu gelangen, die nur Elemente enthält, die allen assoziativen Arrays gemeinsam sind.
Select( :name, :age, :sex, :height, :weight ),
By Row Number
Das war ein Tippfehler aus meinem Beispiel. Select(CommonItems) wäre angebracht.
Ich weiß nicht, ob Concatenate funktionieren wird, Sie können es gerne versuchen
Betreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verketten@uday_guntupalli
Vielen Dank für Ihre großartige Hilfe.
Ich habe nur wenige Kommentare
- Alle Tabellen haben eine unterschiedliche Anzahl von Zeilen.
- Ich möchte die Tabellen verketten (die Anzahl der Zeilen in der endgültigen Tabelle ist die Summe der Zeilenanzahl der einzelnen Tabellen), um die Tabellen nicht zu verbinden. Funktioniert die Verkettungsschleife genauso?
Könnten Sie mir bitte auch helfen, die folgenden Befehle zu verstehen?
- In-Schleife zum Finden allgemeiner Spaltennamen. Können Sie bitte die folgenden Zeilen erläutern?
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>
So viel ich verstanden habe in „ ThisListAsAA " , " Diese Liste " wird als assoziatives Array gespeichert. Bitte helfen Sie, die nächsten beiden Zeilen zu verstehen. - Können Sie bitte in der Schleife zum Verbinden der Tabellen die folgenden Zeilen erläutern?
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
Es gibt keine Spalten mit den Spaltennamen :name, :age usw. und wir können nicht manuell schreiben, um Spalten auszuwählen, da die Anzahl der Spalten sehr groß ist. Wir können auch nicht nach Zeilennummer verknüpfen, da die Anzahl der Zeilen unterschiedlich ist und wir die Tabelle verketten und nicht verknüpfen möchten.
Danke
Betreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verketten@Rajat ,
Ich gehe davon aus (ich weiß nicht, wie gültig das ist), dass Sie die gleiche Anzahl von Zeilen haben.
// 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
);
);
); Betreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verkettenDanke Uday. Ich möchte die gemeinsamen Spalten verketten.Betreff: Mehrere Tabellen mit unterschiedlicher Spaltenreihenfolge verketten@Rajat ,
Lassen Sie uns das von Ihnen beschriebene Problem in mehrere Schritte unterteilen.
Schritt 1: Auswahl der gewünschten Dateien – mit 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 />
Schritt 2: Durchlaufen Sie die Dateien, öffnen und verketten Sie gemeinsame Spalten
Hier habe ich eine Frage an Sie. Gibt es eine Liste von Spalten, die Sie in der endgültigen Tabelle erwarten (oder handelt es sich nur um die gemeinsamen Spalten aller 5 CSV-Dateien)?