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 sum along the week and day axes. We can, of course, remove the labels and use bracket-axis operations to sum along these two axes, giving +/[1] for the week axis and +/[2] for the day axis. However, since the ⍤ rank operator is much more general than bracket axis notation, let's try to find a way to use it in this case!
Notice that ⍤2 will not be immediately correct, since the day and week axes are not the last two axes of our array.
(,⍤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│
└──────┴──────┴──────┴──────┴───────────┴────────────────┴───────────┴──────────────┴──┴──┴──┴─┴──┴─┴──┴─┴──┴──┴──┴─┴──┴─┴──┴─┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴─┘
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 and summing the last two axes, we obtain the result we're looking for.
⍝ 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 labels
2 (↓⍤2) 3 2 1 ⍉ activity
12 15
10 12
14 11
11 14
9 10
13 13
10 12
8 11
7 9
9 10
6 8
10 7
8 12
12 11
15 17
12 14
11 13
14 12
13 16
16 15
15 14
6 8
9 7
8 5
7 9
5 11
10 6
6 8
⍝ Taking the sum
(+/+/⍤2) 2 (↓⍤2) (3 2 1 ⍉ activity)
166 128 197 105
Another way to rotate elements around an array is by rotating along an axis, as opposed to the axes themselves.
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: |: