Liste von Listen ohne for-Schleife transponierenIch hätte gerne eine Methode, um eine Liste von Listen zu transponieren, ohne eine for-Schleife zu verwenden. Das heißt, eine Funktion (nennen Sie sie zum Beispiel "Listtranspose"), die die "Zeilen" und "Spalten" einer Liste von Listen umkehrt, wie folgt:
listlist = {{"cat", "dog", "mouse"}, {"meow", "bark", "squeak"}};
tranlist = Listtranspose(listlist);
Show(tranlist);
/*Result:
{{"cat", "meow"}, {"dog", "bark"}, {"mouse", "squeak}}
Eine alternative Implementierung könnte so aussehen:
listlist = {{"cat", "dog", "mouse"}, {"meow", "bark", "squeak"}};
nr = NItems(listlist);
col1 = listlist[1::nr][1];
col2 = listlist[1::nr][2];
col3 = listlist[1::nr][3];
translist = EvalList({col1, col2, col3});
Mir gefällt die letztere Implementierung besser, da ich möglicherweise nur eine Teilmenge von "Spalten" transponieren muss, nicht die gesamte Liste.
Dies kann natürlich mit einer For-Schleife erfolgen, aber der Grund dafür ist, dass For-Schleifen langsam sein können. Ich arbeite mit großen Textblöcken und ich glaube, dass dies die Dinge für mich erheblich beschleunigen würde.
Kredit an @vince_faller dass du das ursprünglich gefragt hast.Liste von Listen ohne for-Schleife transponieren
SkripterstellungBetreff: Liste von Listen ohne For-Schleife transponierenDenken Sie noch etwas darüber nach.Ich kann die for-Schleife immer noch nicht schlagen, dachte mir aber, ich schreibe das auf, falls es jemandem hilft.
// make a blank data table with the right shape
dt = As Table(J(nr, nc, .), <<PRIVATE></PRIVATE>
Betreff: Liste von Listen ohne For-Schleife transponieren@Craige_Hales Danke für den enormen Einblick, Craig. Ich stimme zu, ich habe einen Geschwindigkeitstest der Methode for loop vs parallel-assign durchgeführt, und parallel-assign war viel langsamer. Mein Listenarray war 718r x 14182c, also> 10 Millionen Elemente. Ich habe das Skript für ca. 10 Minuten ausgeführt und der Vorgang wurde nicht abgeschlossen. Dies scheint ein wenig langsamer zu sein, als Ihre obigen Daten vorhersagen, aber es sind zu viele Variablen zu berücksichtigen (z. B. Computersystem, Verhältnis von Spalten zu Zeilen?). Die For-Schleife ist mit ~10,1 Sekunden für dieselbe Tabelle viel schneller.
Immer noch langsamer als ich möchte. Wäre großartig, eine JMP-Funktion zu haben, die dies intern tun kann.
Betreff: Liste von Listen ohne For-Schleife transponierenAber nach einigen Tests denke ich, dass eine einfache verschachtelte Schleife schneller sein wird als jeder andere JSL-basierte Ansatz.
result = {};
for( c = 1, c <= nc, c += 1,
thisrow = {}; // build a row from a column
for( r = 1, r <= nr, r += 1,
thisrow[r] = testList[r][c];
);
result[c] = thisrow;
);@DonMcCormack - Herausforderung!
The blue-line for-loop is consistently better. The purple JSON-table might overtake it, but I'm running out of memory. The parallel-assign trick begins to fail for large numbers.Die blaue for-Schleife ist durchweg besser. Die lila JSON-Tabelle könnte es überholen, aber mir geht der Speicher aus. Der Parallel-Assign-Trick beginnt bei großen Zahlen fehlzuschlagen.
Die parallele Zuweisung blockiert wahrscheinlich die ganze Zeit Threads gegeneinander. Es schlägt die json-Datentabelle zunächst aufgrund unterschiedlicher Overheads zwischen den beiden.
Betreff: Liste von Listen ohne For-Schleife transponierenJa, es wäre schön, mehr Listenbearbeitungsfunktionen zu haben. Mir fällt kein schöner oder schneller Weg ein, aber nachdem ich ein bisschen gespielt hatte, kam ich auf diesen. Es braucht JMP 15, schlägt in 14 fehl.
list = {{"lion", "tiger", "puma"}, {"lamp", "torch", "pharos"}, {"lark", "toucan", "pigeon"}, {"lawn", "terrace", "patio"}};
jlist = As JSON Expr( list );
dt1 = JSON To Data Table( jlist, invisible(1) );
dt1 << New Column( "row", numeric, setvalues( 1 + Floor( (0 :: (N Rows( dt1 ) - 1)) / N Items( list[1] ) ) ) );
dt2 = dt1 << Split( Split By( :row ), Split( column(dt1,1) ), Sort by Column Property, invisible(1) );
Close( dt1, nosave );
transposed = dt2[0, 0];
Close( dt2, nosave );
Show( list, transposed );list = {{"Löwe", "Tiger", "Puma"}, {"Lampe", "Fackel", "Pharos"}, {"Lerche", "Tukan", "Taube"}, {"Rasen", "Terrasse", "Patio"}};
transponiert = {{"Löwe", "Lampe", "Lerche", "Rasen"}, {"Tiger", "Fackel", "Tukan", "Terrasse"}, {"Puma", " Pharos ", "Taube", "Terrasse"}};
Blenden Sie die Zwischentabellen ein, um zu sehen, was es tut. Eine echte Lösung sollte mit Zeilen ungleicher Länge umgehen.
Betreff: Liste von Listen ohne For-Schleife transponieren@Craige_Hales hat eine großartige Erklärung geschrieben, die ich regelmäßig verwende.Multithreading-Fehlerbehebung mit Parallel Assign
Betreff: Liste von Listen ohne For-Schleife transponieren@vince_faller
Verstand == Durchgebrannt.
Noch nie zuvor von der Parallel Assign-Funktion gehört. Ich habe es ausprobiert, und ja, es funktioniert. Obwohl ich mit Zeichenfolgen arbeite und dies technisch gesehen eine Matrixfunktion ist, ist es irgendwie egal. Es wird interessant sein, damit zu spielen und zu sehen, ob es schneller als eine for-Schleife ist. Werde versuchen, hier zu aktualisieren, sobald ich es weiß.
Danke für die Idee!
Betreff: Liste von Listen ohne For-Schleife transponierenIch schwöre hoch und runter, dass ich gesehen habe, wie jemand etwas in der Art von getan hat
{"cat", "dog", "mouse", "meow", "bark", "squeak"}[[1 1, 1 1]]
// and had it return
{{"cat", "cat"}, {"cat", "cat"}}
während eines Vortrags bei Discovery, aber ich konnte es nie nachstellen.Es könnte alles ein Traum gewesen sein?
Wenn ich mich recht erinnere, haben sie irgendwie eine neue Liste aus einer flachen Liste in einer solchen Zeile geformt.Ich erinnere mich wahrscheinlich nicht richtig.
Davon abgesehen können Sie wahrscheinlich sehr schnell parallel zuweisen
names default to here(1);
listlist = {{"cat", "dog", "mouse"}, {"meow", "bark", "squeak"}};
m = J(nc, nr, -1);
::trans_list = Aslist(m);
Parallel Assign({l = listlist},
m[a, b] = (
::trans_list[a][b] = l[b][a];
)
);
show(::trans_list);