I knew he swapped those numbers!
This part will cover
- Transpose
- Reverse
- Rotate
With data stored in higher dimensional arrays, it is often necessary to rotate, flip, and transpose the axes of these arrays in order to make sense of them. This is especially true in the case of highly structured data.
Let's look at an array tracking the number of replies a user has posted per day, for two weeks
w1 ← (⊂'Week 1') ('RedScanLine' 'frequencySniffer' 'dataMoshpit' 'Radiovangelist') (12 8 15 6) (10 7 12 9) (14 9 11 8) (11 6 14 7) (9 10 13 5) (13 8 16 10) (10 12 15 6)
↑w1
┌───────────┬────────────────┬───────────┬──────────────┐
│Week 1 │ │ │ │
├───────────┼────────────────┼───────────┼──────────────┤
│RedScanLine│frequencySniffer│dataMoshpit│Radiovangelist│
├───────────┼────────────────┼───────────┼──────────────┤
│12 │8 │15 │6 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │7 │12 │9 │
├───────────┼────────────────┼───────────┼──────────────┤
│14 │9 │11 │8 │
├───────────┼────────────────┼───────────┼──────────────┤
│11 │6 │14 │7 │
├───────────┼────────────────┼───────────┼──────────────┤
│9 │10 │13 │5 │
├───────────┼────────────────┼───────────┼──────────────┤
│13 │8 │16 │10 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │12 │15 │6 │
└───────────┴────────────────┴───────────┴──────────────┘
w2 ← (⊂'Week 2') ('RedScanLine' 'frequencySniffer' 'dataMoshpit' 'Radiovangelist') (15 11 17 8) (12 9 14 7) (11 10 13 5) (14 8 12 9) (10 7 16 11) (13 12 15 6) (12 11 14 8)
↑w2
┌───────────┬────────────────┬───────────┬──────────────┐
│Week 2 │ │ │ │
├───────────┼────────────────┼───────────┼──────────────┤
│RedScanLine│frequencySniffer│dataMoshpit│Radiovangelist│
├───────────┼────────────────┼───────────┼──────────────┤
│15 │11 │17 │8 │
├───────────┼────────────────┼───────────┼──────────────┤
│12 │9 │14 │7 │
├───────────┼────────────────┼───────────┼──────────────┤
│11 │10 │13 │5 │
├───────────┼────────────────┼───────────┼──────────────┤
│14 │8 │12 │9 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │7 │16 │11 │
├───────────┼────────────────┼───────────┼──────────────┤
│13 │12 │15 │6 │
├───────────┼────────────────┼───────────┼──────────────┤
│12 │11 │14 │8 │
└───────────┴────────────────┴───────────┴──────────────┘
activity ← ↑↑w1 w2
┌───────────┬────────────────┬───────────┬──────────────┐
│Week 1 │ │ │ │
├───────────┼────────────────┼───────────┼──────────────┤
│RedScanLine│frequencySniffer│dataMoshpit│Radiovangelist│
├───────────┼────────────────┼───────────┼──────────────┤
│12 │8 │15 │6 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │7 │12 │9 │
├───────────┼────────────────┼───────────┼──────────────┤
│14 │9 │11 │8 │
├───────────┼────────────────┼───────────┼──────────────┤
│11 │6 │14 │7 │
├───────────┼────────────────┼───────────┼──────────────┤
│9 │10 │13 │5 │
├───────────┼────────────────┼───────────┼──────────────┤
│13 │8 │16 │10 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │12 │15 │6 │
└───────────┴────────────────┴───────────┴──────────────┘
┌───────────┬────────────────┬───────────┬──────────────┐
│Week 2 │ │ │ │
├───────────┼────────────────┼───────────┼──────────────┤
│RedScanLine│frequencySniffer│dataMoshpit│Radiovangelist│
├───────────┼────────────────┼───────────┼──────────────┤
│15 │11 │17 │8 │
├───────────┼────────────────┼───────────┼──────────────┤
│12 │9 │14 │7 │
├───────────┼────────────────┼───────────┼──────────────┤
│11 │10 │13 │5 │
├───────────┼────────────────┼───────────┼──────────────┤
│14 │8 │12 │9 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │7 │16 │11 │
├───────────┼────────────────┼───────────┼──────────────┤
│13 │12 │15 │6 │
├───────────┼────────────────┼───────────┼──────────────┤
│12 │11 │14 │8 │
└───────────┴────────────────┴───────────┴──────────────┘
The array above is structured along three axes, the first being the week, the second being the day of the week, and the third is the user. Note that there are also several non-data entries that are used to make the tables easier to read.
⍝ Two weeks, 7 days, 4 users (Note that there are two rows which are used for labels)
⍴ activity
2 9 4
To get the total list of replies for each user, we need to forget the day and week axes to be left with only user information. If we try to use the rank operator to enlist along the 2-cells of this array, we don't get what we want.
(,⍤2)activity
┌──────┬──────┬──────┬──────┬───────────┬────────────────┬───────────┬──────────────┬──┬──┬──┬─┬──┬─┬──┬─┬──┬──┬──┬─┬──┬─┬──┬─┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬─┐
│Week 1│ │ │ │RedScanLine│frequencySniffer│dataMoshpit│Radiovangelist│12│8 │15│6│10│7│12│9│14│9 │11│8│11│6│14│7│9 │10│13│5 │13│8 │16│10│10│12│15│6│
├──────┼──────┼──────┼──────┼───────────┼────────────────┼───────────┼──────────────┼──┼──┼──┼─┼──┼─┼──┼─┼──┼──┼──┼─┼──┼─┼──┼─┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼─┤
│Week 2│ │ │ │RedScanLine│frequencySniffer│dataMoshpit│Radiovangelist│15│11│17│8│12│9│14│7│11│10│13│5│14│8│12│9│10│7 │16│11│13│12│15│6 │12│11│14│8│
└──────┴──────┴──────┴──────┴───────────┴────────────────┴───────────┴──────────────┴──┴──┴──┴─┴──┴─┴──┴─┴──┴──┴──┴─┴──┴─┴──┴─┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴─┘
This is because the last two axes of the array are Day and User.
⍝ First week
activity[1;;]
┌───────────┬────────────────┬───────────┬──────────────┐
│Week 1 │ │ │ │
├───────────┼────────────────┼───────────┼──────────────┤
│RedScanLine│frequencySniffer│dataMoshpit│Radiovangelist│
├───────────┼────────────────┼───────────┼──────────────┤
│12 │8 │15 │6 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │7 │12 │9 │
├───────────┼────────────────┼───────────┼──────────────┤
│14 │9 │11 │8 │
├───────────┼────────────────┼───────────┼──────────────┤
│11 │6 │14 │7 │
├───────────┼────────────────┼───────────┼──────────────┤
│9 │10 │13 │5 │
├───────────┼────────────────┼───────────┼──────────────┤
│13 │8 │16 │10 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │12 │15 │6 │
└───────────┴────────────────┴───────────┴──────────────┘
⍝ First day of either week
activity[;3;]
12 8 15 6
15 11 17 8
⍝ First user
activity[;;1]
┌──────┬───────────┬──┬──┬──┬──┬──┬──┬──┐
│Week 1│RedScanLine│12│10│14│11│9 │13│10│
├──────┼───────────┼──┼──┼──┼──┼──┼──┼──┤
│Week 2│RedScanLine│15│12│11│14│10│13│12│
└──────┴───────────┴──┴──┴──┴──┴──┴──┴──┘
The way to solve this is to swap the Week and User axes to get an array where the last axes are Week and Day, this problem is easily solved by the ⍉ transpose function.
The left argument to the transpose function is a list of integers starting from 1, which represents where each axes is in the resulting array. For example, 1 2 3 ⍉ activity
is the same as activity
, but 3 2 1⍉activity
swaps the first and third axis.
⍝ Week × Day × User
1 2 3 ⍉ activity
┌───────────┬────────────────┬───────────┬──────────────┐
│Week 1 │ │ │ │
├───────────┼────────────────┼───────────┼──────────────┤
│RedScanLine│frequencySniffer│dataMoshpit│Radiovangelist│
├───────────┼────────────────┼───────────┼──────────────┤
│12 │8 │15 │6 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │7 │12 │9 │
├───────────┼────────────────┼───────────┼──────────────┤
│14 │9 │11 │8 │
├───────────┼────────────────┼───────────┼──────────────┤
│11 │6 │14 │7 │
├───────────┼────────────────┼───────────┼──────────────┤
│9 │10 │13 │5 │
├───────────┼────────────────┼───────────┼──────────────┤
│13 │8 │16 │10 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │12 │15 │6 │
└───────────┴────────────────┴───────────┴──────────────┘
┌───────────┬────────────────┬───────────┬──────────────┐
│Week 2 │ │ │ │
├───────────┼────────────────┼───────────┼──────────────┤
│RedScanLine│frequencySniffer│dataMoshpit│Radiovangelist│
├───────────┼────────────────┼───────────┼──────────────┤
│15 │11 │17 │8 │
├───────────┼────────────────┼───────────┼──────────────┤
│12 │9 │14 │7 │
├───────────┼────────────────┼───────────┼──────────────┤
│11 │10 │13 │5 │
├───────────┼────────────────┼───────────┼──────────────┤
│14 │8 │12 │9 │
├───────────┼────────────────┼───────────┼──────────────┤
│10 │7 │16 │11 │
├───────────┼────────────────┼───────────┼──────────────┤
│13 │12 │15 │6 │
├───────────┼────────────────┼───────────┼──────────────┤
│12 │11 │14 │8 │
└───────────┴────────────────┴───────────┴──────────────┘
⍝ User × Week × Day
3 2 1 ⍉ activity
┌────────────────┬────────────────┐
│Week 1 │Week 2 │
├────────────────┼────────────────┤
│RedScanLine │RedScanLine │
├────────────────┼────────────────┤
│12 │15 │
├────────────────┼────────────────┤
│10 │12 │
├────────────────┼────────────────┤
│14 │11 │
├────────────────┼────────────────┤
│11 │14 │
├────────────────┼────────────────┤
│9 │10 │
├────────────────┼────────────────┤
│13 │13 │
├────────────────┼────────────────┤
│10 │12 │
└────────────────┴────────────────┘
┌────────────────┬────────────────┐
│ │ │
├────────────────┼────────────────┤
│frequencySniffer│frequencySniffer│
├────────────────┼────────────────┤
│8 │11 │
├────────────────┼────────────────┤
│7 │9 │
├────────────────┼────────────────┤
│9 │10 │
├────────────────┼────────────────┤
│6 │8 │
├────────────────┼────────────────┤
│10 │7 │
├────────────────┼────────────────┤
│8 │12 │
├────────────────┼────────────────┤
│12 │11 │
└────────────────┴────────────────┘
┌────────────────┬────────────────┐
│ │ │
├────────────────┼────────────────┤
│dataMoshpit │dataMoshpit │
├────────────────┼────────────────┤
│15 │17 │
├────────────────┼────────────────┤
│12 │14 │
├────────────────┼────────────────┤
│11 │13 │
├────────────────┼────────────────┤
│14 │12 │
├────────────────┼────────────────┤
│13 │16 │
├────────────────┼────────────────┤
│16 │15 │
├────────────────┼────────────────┤
│15 │14 │
└────────────────┴────────────────┘
┌────────────────┬────────────────┐
│ │ │
├────────────────┼────────────────┤
│Radiovangelist │Radiovangelist │
├────────────────┼────────────────┤
│6 │8 │
├────────────────┼────────────────┤
│9 │7 │
├────────────────┼────────────────┤
│8 │5 │
├────────────────┼────────────────┤
│7 │9 │
├────────────────┼────────────────┤
│5 │11 │
├────────────────┼────────────────┤
│10 │6 │
├────────────────┼────────────────┤
│6 │8 │
└────────────────┴────────────────┘
Removing the labels
⍝ Check how ⍤2 acts on the above matrix
(⊂⍤2)3 2 1 ⍉ activity
┌─────────────────────────┬───────────────────────────────────┬─────────────────────────┬───────────────────────────────┐
│┌───────────┬───────────┐│┌────────────────┬────────────────┐│┌───────────┬───────────┐│┌──────────────┬──────────────┐│
││Week 1 │Week 2 │││ │ │││ │ │││ │ ││
│├───────────┼───────────┤│├────────────────┼────────────────┤│├───────────┼───────────┤│├──────────────┼──────────────┤│
││RedScanLine│RedScanLine│││frequencySniffer│frequencySniffer│││dataMoshpit│dataMoshpit│││Radiovangelist│Radiovangelist││
│├───────────┼───────────┤│├────────────────┼────────────────┤│├───────────┼───────────┤│├──────────────┼──────────────┤│
││12 │15 │││8 │11 │││15 │17 │││6 │8 ││
│├───────────┼───────────┤│├────────────────┼────────────────┤│├───────────┼───────────┤│├──────────────┼──────────────┤│
││10 │12 │││7 │9 │││12 │14 │││9 │7 ││
│├───────────┼───────────┤│├────────────────┼────────────────┤│├───────────┼───────────┤│├──────────────┼──────────────┤│
││14 │11 │││9 │10 │││11 │13 │││8 │5 ││
│├───────────┼───────────┤│├────────────────┼────────────────┤│├───────────┼───────────┤│├──────────────┼──────────────┤│
││11 │14 │││6 │8 │││14 │12 │││7 │9 ││
│├───────────┼───────────┤│├────────────────┼────────────────┤│├───────────┼───────────┤│├──────────────┼──────────────┤│
││9 │10 │││10 │7 │││13 │16 │││5 │11 ││
│├───────────┼───────────┤│├────────────────┼────────────────┤│├───────────┼───────────┤│├──────────────┼──────────────┤│
││13 │13 │││8 │12 │││16 │15 │││10 │6 ││
│├───────────┼───────────┤│├────────────────┼────────────────┤│├───────────┼───────────┤│├──────────────┼──────────────┤│
││10 │12 │││12 │11 │││15 │14 │││6 │8 ││
│└───────────┴───────────┘│└────────────────┴────────────────┘│└───────────┴───────────┘│└──────────────┴──────────────┘│
└─────────────────────────┴───────────────────────────────────┴─────────────────────────┴───────────────────────────────┘
⍝ Use drop ↓ to remove the week label
1 (↓⍤2) 3 2 1 ⍉ activity
┌────────────────┬────────────────┐
│RedScanLine │RedScanLine │
├────────────────┼────────────────┤
│12 │15 │
├────────────────┼────────────────┤
│10 │12 │
├────────────────┼────────────────┤
│14 │11 │
├────────────────┼────────────────┤
│11 │14 │
├────────────────┼────────────────┤
│9 │10 │
├────────────────┼────────────────┤
│13 │13 │
├────────────────┼────────────────┤
│10 │12 │
└────────────────┴────────────────┘
┌────────────────┬────────────────┐
│frequencySniffer│frequencySniffer│
├────────────────┼────────────────┤
│8 │11 │
├────────────────┼────────────────┤
│7 │9 │
├────────────────┼────────────────┤
│9 │10 │
├────────────────┼────────────────┤
│6 │8 │
├────────────────┼────────────────┤
│10 │7 │
├────────────────┼────────────────┤
│8 │12 │
├────────────────┼────────────────┤
│12 │11 │
└────────────────┴────────────────┘
┌────────────────┬────────────────┐
│dataMoshpit │dataMoshpit │
├────────────────┼────────────────┤
│15 │17 │
├────────────────┼────────────────┤
│12 │14 │
├────────────────┼────────────────┤
│11 │13 │
├────────────────┼────────────────┤
│14 │12 │
├────────────────┼────────────────┤
│13 │16 │
├────────────────┼────────────────┤
│16 │15 │
├────────────────┼────────────────┤
│15 │14 │
└────────────────┴────────────────┘
┌────────────────┬────────────────┐
│Radiovangelist │Radiovangelist │
├────────────────┼────────────────┤
│6 │8 │
├────────────────┼────────────────┤
│9 │7 │
├────────────────┼────────────────┤
│8 │5 │
├────────────────┼────────────────┤
│7 │9 │
├────────────────┼────────────────┤
│5 │11 │
├────────────────┼────────────────┤
│10 │6 │
├────────────────┼────────────────┤
│6 │8 │
└────────────────┴────────────────┘
Finally obtaining the replies per user per day
⍝ Ravel the above 2-cells to get the replies per day for every user
(,⍤2) 1 (↓⍤2) (3 2 1 ⍉ activity)
┌────────────────┬────────────────┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│RedScanLine │RedScanLine │12│15│10│12│14│11│11│14│9 │10│13│13│10│12│
├────────────────┼────────────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│frequencySniffer│frequencySniffer│8 │11│7 │9 │9 │10│6 │8 │10│7 │8 │12│12│11│
├────────────────┼────────────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│dataMoshpit │dataMoshpit │15│17│12│14│11│13│14│12│13│16│16│15│15│14│
├────────────────┼────────────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│Radiovangelist │Radiovangelist │6 │8 │9 │7 │8 │5 │7 │9 │5 │11│10│6 │6 │8 │
└────────────────┴────────────────┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
⍝ Remove the duplicate user label using (↓⍤1) drop on 1-cells
1 (↓⍤1) (,⍤2) 1(↓⍤2) (3 2 1 ⍉ activity)
┌────────────────┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│RedScanLine │12│15│10│12│14│11│11│14│9 │10│13│13│10│12│
├────────────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│frequencySniffer│8 │11│7 │9 │9 │10│6 │8 │10│7 │8 │12│12│11│
├────────────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│dataMoshpit │15│17│12│14│11│13│14│12│13│16│16│15│15│14│
├────────────────┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│Radiovangelist │6 │8 │9 │7 │8 │5 │7 │9 │5 │11│10│6 │6 │8 │
└────────────────┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
More examples of transpose
SYMBOLS ← 2 3 2 ⍴ 'A1B2C3あ一い二う三'
⍝ The first axis is from English to Japanese, the second axis is alphanumeric order, and the third axis is from letters to numbers
SYMBOLS
A1
B2
C3
あ一
い二
う三
⍝ Transposing the last two axes, so that the second axis is now from letters to numbers
1 3 2⍉SYMBOLS
ABC
123
あいう
一二三
⍝ Transposing the first two axis, so that the first axis is now alphanumeric order
2 1 3⍉SYMBOLS
A1
あ一
B2
い二
C3
う三
⍝ Transposing the first and last axis, so that the first axis is now letters to numbers
3 2 1⍉SYMBOLS
Aあ
Bい
Cう
1一
2二
3三
The dyadic ⌽
⊖
rotate functions rotate an array by an amount specific by the left argument, around a specific axis.
3⌽¨'hotbloods' 'mentally' 'outbreak' 'clean' 'kyoto'
bloodshot tallymen breakout ancle tokyo
Another example:
SAD_EMOTICONS ← '):' ':c' ']:' ')-:' 'D:' '>:(' ':/' ':x' ':|'
Notice that some of the sad emoticons can be turned into happy emoticons by reflecting the emoticon vertically, turning the frown upside down! The monadic ⌽ ⊖ reverse functions reflect an array along the horizontal (last) or vertical (first) axis.
⌽ '):'
:)
⌽ SAD_EMOTICONS
): :c ]: )-: D: >:( :/ :x :|
⌽¨SAD_EMOTICONS
:) c: :] :-) :D (:> /: x: |: