Как и в случае большинства символов APL, ⍉
при вызове с одним аргументом (транспонирование) имеет разные значения по сравнению с двумя аргументами (диадические измерения транспонирования / переупорядочения). Эта проблема касается последнего, который действует аналогично numpy.moveaxis
Python или permute
MATLAB, но является более мощным.
order ⍉ A
когда order
есть разные записи
Когда все члены order
различны, order ⍉ A
эквивалентно:
numpy.moveaxis(A, tuple(range(len(A.shape)), order)
в Python, илиpermute(A,order)
в MATLAB. Цитирование из документации последнего:
B = permute (A, order) переставляет размеры A так, чтобы они были в порядке, указанном векторным порядком. Результирующий массив B имеет те же значения, что и A, но порядок индексов, необходимых для доступа к какому-либо конкретному элементу, изменяется в соответствии с порядком.
Например, предположим, что A
это трехмерный массив, и пусть B ← (2 0 1)⍉A
. Тогда B таков, что B[x0,x1,x2] = A[x2,x0,x1]
для всехx2,x0,x1
order ⍉ A
когда order
повторил записи
Когда order
есть повторенные записи, мы берем диагональный срез массива. Например, пусть A будет массивом 2x3x4. B ← (0 0 1)⍉A
берет диагональный срез, A
чтобы создать B
такое, что B[x0,x1] = A[x0,x0,x1]
. Обратите внимание, что B
это массив 2x4: если бы он был 3x4, нам нужно было бы установить, B[2, x1] = A[2, 2, x1]
что было бы за пределами A
. Вообще-то k
измерение B
будет минимальным из всех A.shape[i]
таких, что order[i] = k
.
пример
Рассмотрим диадическое транспонирование, order⍉A
где order = [2, 1, 0]
A - 3x4x5
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]]]
В результате получается массив 5x4x3 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]]]
Обратите внимание, что когда, например, (x0, x1, x2) = (4,1,2) мы имеем B[x0,x1,x2] = A[x2, x1, x0] = A[2,1,4] = 49
.
Если вместо этого order = [0, 0, 0]
и A
как указано выше, мы получим B
1-мерный массив size-3, B = [0, 26, 52]
чтобыB[1] = B[x0] = A[x0,x0,x0] = A[1,1,1] = 26
вход
Здесь мы используем 0-индексирование, но вы также можете использовать 1-индексирование, как по умолчанию APL.
Многомерный или вложенный массив
A
размером n ≥ 1.Список
order
из n натуральных чисел, состоящий из целых чисел {0,1, ..., k} (или {1, ..., k + 1} для 1-индекса) для некоторого k < n в любом порядке, возможно с повторениями.
Вывод
- Многомерный или вложенный массив, представляющий результат применения двоичной транспонирования с этими аргументами. (Выход будет иметь размерность k + 1. )
Вы можете написать полную программу, функцию и т. Д. В соответствии с действующим стандартом meta.
Если ваш язык имеет встроенную функцию, рекомендуется также написать решение без встроенной функции ради интересного ответа.
Контрольные примеры
Реализация ссылочной Python в ближайшее время.
Примечание для чтения тестовых случаев: в APL предпоследняя и конечная оси массива расположены вдоль столбцов и строк в указанном порядке.
источник
⍉
P⍉
который использует индексы обращенной оси по умолчанию, так⍉A
же, как(2 1 0)⍉A
еслиA
это 3-мерный массив и в целом⍉A
это(⌽⍳≢⍴A)⍉A
.[number-of-dimensions,first-dimension-length,second-dimension-length,…,last-dimension-length,first-element,second-element,…,last-element]
.Ответы:
APL (Dyalog Unicode) , 34 байта SBCS
Это код моего коллеги (слегка измененный из Roger Hui : История APL в 50 функциях , глава 30 ), опубликованный с явного разрешения.
Лямбда анонимного молчаливого инфикса (может использоваться как дроп-ин
⍉
).Попробуйте онлайн!
{
…}
Дфн;⍺
левый аргумент (оси),⍵
правый аргумент (массив),например,
[2,2,1]
и[[[1,2],[3,4]]]
⍵[
…]
Индексировать массив с помощью:(⍴⍵)[
…]
Форма (длина осей) массива, проиндексированная:[1,2,2]
⍋⍺
вектор классификации (индексы, которые будут сортировать их) осей[3,1,2]
[2,1,2]
⍺[⍋⍺]{
...}⌸
использовать отсортированные оси в качестве ключей для группировки и для каждой группы:[1,2,2]
→{"1":[2],"2":[1,2]}
{⌊/⍵}
найти наименьшую длину оси{"1":2,"2":1}
→[2,1]
⍳
генерировать индексы в декартовой системе этих измерений[[[1,1]],[[2,1]]]
,¨
убедитесь, что индексы каждой координаты являются вектором (будут скалярными, если⍵
вектор)[[[1,1]],[[2,1]]]
(
…)⌷¨
Индексировать в каждом из них следующее:⊂⊂⍺
оси (дважды заключенные; один раз для⌷
выбора этих ячеек вдоль первой и единственной оси и один раз для¨
объединения каждого вектора справа со всем набором осей слева)2 1 2
[[[1,1,1]],[[1,2,1]]]
[[1],[3]]
источник