Dyadische Transponierung


9

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.moveaxisin Python oder permuteMATLAB verhält, jedoch leistungsfähiger ist.

order ⍉ AWann orderhat eindeutige Einträge

Wenn alle Mitglieder von verschieden ordersind, order ⍉ Aentspricht dies:

  • numpy.moveaxis(A, tuple(range(len(A.shape)), order) in Python oder
  • permute(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 Ahandelt 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 ⍉ Awann orderhat Einträge wiederholt

Bei orderwiederholten Einträgen nehmen wir einen diagonalen Ausschnitt aus dem Array. Zum Beispiel sei A ein 2x3x4-Array. B ← (0 0 1)⍉Animmt eine diagonale Scheibe mit A, um Bso zu erstellen , dass B[x0,x1] = A[x0,x0,x1]. Beachten Sie, dass dies Bein 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 kth Dimension von Bdas Minimum von allen, A.shape[i]so dass order[i] = k.

Beispiel

Betrachten Sie die dyadische Transponierte, order⍉Awobei 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 Awie oben, dann hätten wir die Ausgabe Bdas 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 Amit der Dimension n ≥ 1.

  • Eine Liste ordervon 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

Testfälle auf TIO

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.


4
APL, 1 Byte
::

1
Tatsächlich verwenden viele APL-Symbole nur ein zweites Standardargument, wenn sie mit einem Argument aufgerufen werden. Dies beinhaltet , welche die umgekehrte Achsindizes als Standard verwendet wird , so ⍉Aist das gleiche wie (2 1 0)⍉Awenn Aein 3-dimensionales Array und im allgemeinen ⍉Aist (⌽⍳≢⍴A)⍉A.
Adám

@lirtosiast Frage zu I / O: Kann ein mehrdimensionales Array als ein Paar aus Form (Liste der Dimensionen) und Inhalt (alle Elemente in lexikografischer Reihenfolge ihrer Indizes) dargestellt werden?
ngn

@ngn Ich würde vorerst nein sagen, aber Sie sollten auf Meta fragen, ob dieses Format standardmäßig akzeptabel ist.
Lirtosiast

@lirtosiast Anekdotisch speichert Dyalog APL Arrays intern als [number-of-dimensions,first-dimension-length,second-dimension-length,…,last-dimension-length,first-element,second-element,…,last-element].
Adám

Antworten:


4

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]]

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.