Wie bei den meisten APL-Symbolen ⍉
hat es unterschiedliche Bedeutungen, wenn es mit einem Argument (Transponierung) gegenüber zwei Argumenten (dyadische Transponierungs- / Neuordnungsdimensionen) aufgerufen wird. Diese Herausforderung betrifft letztere, die sich ähnlich wie numpy.moveaxis
in Python oder permute
MATLAB verhält, jedoch leistungsfähiger ist.
order ⍉ A
Wann order
hat eindeutige Einträge
Wenn alle Mitglieder von verschieden order
sind, order ⍉ A
entspricht dies:
numpy.moveaxis(A, tuple(range(len(A.shape)), order)
in Python oderpermute(A,order)
in MATLAB. Zitat aus der Dokumentation des letzteren:
B = Permute (A, Ordnung) ordnet die Dimensionen von A so um, dass sie in der durch die Vektorreihenfolge angegebenen Reihenfolge liegen. Das resultierende Array B hat die gleichen Werte wie A, aber die Reihenfolge der Indizes, die für den Zugriff auf ein bestimmtes Element erforderlich sind, wird gemäß der angegebenen Reihenfolge neu angeordnet.
Angenommen, es A
handelt sich um ein 3D-Array, und lassen Sie B ← (2 0 1)⍉A
. Dann ist B so, dass B[x0,x1,x2] = A[x2,x0,x1]
für allex2,x0,x1
order ⍉ A
wann order
hat Einträge wiederholt
Bei order
wiederholten Einträgen nehmen wir einen diagonalen Ausschnitt aus dem Array. Zum Beispiel sei A ein 2x3x4-Array. B ← (0 0 1)⍉A
nimmt eine diagonale Scheibe mit A
, um B
so zu erstellen , dass B[x0,x1] = A[x0,x0,x1]
. Beachten Sie, dass dies B
ein 2x4-Array ist: Wenn es 3x4 wäre, müssten wir festlegen, B[2, x1] = A[2, 2, x1]
welches außerhalb der Grenzen von liegt A
. Im Allgemeinen ist die k
th Dimension von B
das Minimum von allen, A.shape[i]
so dass order[i] = k
.
Beispiel
Betrachten Sie die dyadische Transponierte, order⍉A
wobei order = [2, 1, 0]
und A 3x4x5 ist
A =
[[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
[[20 21 22 23 24]
[25 26 27 28 29]
[30 31 32 33 34]
[35 36 37 38 39]]
[[40 41 42 43 44]
[45 46 47 48 49]
[50 51 52 53 54]
[55 56 57 58 59]]]
Das Ergebnis ist das 5x4x3-Array B =
[[[ 0 20 40]
[ 5 25 45]
[10 30 50]
[15 35 55]]
[[ 1 21 41]
[ 6 26 46]
[11 31 51]
[16 36 56]]
[[ 2 22 42]
[ 7 27 47]
[12 32 52]
[17 37 57]]
[[ 3 23 43]
[ 8 28 48]
[13 33 53]
[18 38 58]]
[[ 4 24 44]
[ 9 29 49]
[14 34 54]
[19 39 59]]]
Beachten Sie, dass wir zum Beispiel (x0, x1, x2) = (4,1,2) haben B[x0,x1,x2] = A[x2, x1, x0] = A[2,1,4] = 49
.
Wenn stattdessen order = [0, 0, 0]
und A
wie oben, dann hätten wir die Ausgabe B
das 1-dimensionale Array der Größe 3, B = [0, 26, 52]
so dassB[1] = B[x0] = A[x0,x0,x0] = A[1,1,1] = 26
Eingang
Hier verwenden wir die 0-Indizierung, aber Sie können auch die 1-Indizierung verwenden, wie dies die APL-Standardeinstellung ist.
Ein mehrdimensionales oder verschachteltes Array
A
mit der Dimension n ≥ 1.Eine Liste
order
von n positiven ganzen Zahlen, bestehend aus den ganzen Zahlen {0,1, ..., k} (oder {1, ..., k + 1} für 1-Index) für einige k < n , möglicherweise in beliebiger Reihenfolge mit Wiederholungen.
Ausgabe
- Ein mehrdimensionales oder verschachteltes Array, das das Ergebnis der Anwendung der dyadischen Transponierung mit diesen Argumenten darstellt. (Die Ausgabe hat die Dimension k + 1. )
Sie können ein vollständiges Programm, eine Funktion usw. schreiben, wie es der aktuelle Standard für Meta erlaubt.
Wenn Ihre Sprache eingebaut ist, wird empfohlen, auch eine Lösung ohne eingebaute Sprache zu schreiben, um eine interessante Antwort zu erhalten.
Testfälle
Referenz Python-Implementierung in Kürze.
Hinweis zum Lesen von Testfällen: In APL befinden sich die vorletzten und letzten Achsen eines Arrays entlang von Spalten und Zeilen in dieser Reihenfolge.
quelle
⍉
⍉
welche die umgekehrte Achsindizes als Standard verwendet wird , so⍉A
ist das gleiche wie(2 1 0)⍉A
wennA
ein 3-dimensionales Array und im allgemeinen⍉A
ist(⌽⍳≢⍴A)⍉A
.[number-of-dimensions,first-dimension-length,second-dimension-length,…,last-dimension-length,first-element,second-element,…,last-element]
.Antworten:
APL (Dyalog Unicode) , 34 Byte SBCS
Dies ist der Code meines Kollegen (leicht modifiziert von Roger Hui : Eine Geschichte der APL in 50 Funktionen , Kapitel 30 ), der mit ausdrücklicher Genehmigung veröffentlicht wurde.
Anonymes implizites Infix Lambda (kann als Drop-In für verwendet werden
⍉
).Probieren Sie es online aus!
{
…}
Dfn;⍺
ist linkes Argument (Achsen),⍵
ist rechtes Argument (Array)ZB
[2,2,1]
und[[[1,2],[3,4]]]
⍵[
…]
Indizieren Sie das Array mit:(⍴⍵)[
…]
Die Form (Länge der Achsen) des Arrays, indiziert durch:[1,2,2]
⍋⍺
der Bewertungsvektor (die Indizes, die sie sortieren würden) der Achsen[3,1,2]
[2,1,2]
⍺[⍋⍺]{
…}⌸
Verwenden Sie die sortierten Achsen als Schlüssel, um dies zu gruppieren, und für jede Gruppe:[1,2,2]
→{"1":[2],"2":[1,2]}
{⌊/⍵}
finde die niedrigste Achsenlänge{"1":2,"2":1}
→[2,1]
⍳
Generieren Sie die Indizes in einem kartesischen System dieser Dimensionen[[[1,1]],[[2,1]]]
,¨
Stellen Sie sicher, dass die Indizes jeder Koordinate ein Vektor sind (wäre skalar, wenn⍵
es sich um einen Vektor handelt).[[[1,1]],[[2,1]]]
(
…)⌷¨
Index in jeden von denen mit den folgenden:⊂⊂⍺
die Achsen (doppelt eingeschlossen; einmal⌷
zum Auswählen dieser Zellen entlang der ersten und einzigen Achse und einmal¨
zum Koppeln jedes Vektors auf der rechten Seite mit dem gesamten Satz von Achsen auf der linken Seite)2 1 2
[[[1,1,1]],[[1,2,1]]]
[[1],[3]]
quelle