如何在Dyalog APL中操作多个嵌套数组?

3

我收到了填充有字母数字值的矩阵,其中不包含小写字母,如下所示:

XX11X1X
XX88X8X
Y000YYY
ZZZZ789
ABABABC

我被委托计算每行重复出现的次数,并根据重复字符的排名进行积分。我使用了{⍺ (≢⍵)}⌸¨ ↓ m来帮助我。对于上面的示例,我会得到类似于这样的结果:

X 4  X 4  Y 4  Z 4  A 3 
1 3  8 3  0 3  7 1  B 3 
               8 1  C 1 
               9 1     

这很棒,但现在我需要编写一个函数,能够将数字与每个字母相乘。我可以使用访问第一个矩阵,但是我完全不知道如何访问其他矩阵。我可以简单地编写⊃w[2]⊃w[3]等等,但我需要一种方法来在一个函数中同时更改每个矩阵。对于这个示例,排名数组如下:ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210因此,对于第一个数组XX11X1X,对应的是:
X 4
1 3

因此,X在数组中排名第三,所以对应的是3,1在第35个位置,所以是35。最终得分可能类似于(3×104) + (35×103)。我的最大问题不一定是评分部分,而是能够在一个函数中单独访问每个矩阵。所以对于这个嵌套数组:

 X 4  X 4  Y 4  Z 4  A 3 
 1 3  8 3  0 3  7 1  B 3 
                8 1  C 1 
                9 1      

如果我输入arr[1],它会返回一个标量。
 X 4
 1 3

我想知道如何获取矩阵的列。使用⍴ arr[1]并没有给我确认,所以我可以使用⊃arr[1]来获取矩阵本身并逐个访问每一列。这就是我卡住的地方。我正在尝试编写一个函数来对每个矩阵进行计算,然后将这些结果保存到数组中。我可以轻松地对第一个矩阵进行计算,但我无法对所有矩阵进行计算。我可能在使用{⍺ (≢⍵)}⌸¨ ↓ m时犯了错误。谢谢。


你具体想如何操作中间结果(特别是如何“将数字与每个字母相乘”)?能否包含预期结果? - Bubbler
@Bubbler,所以我需要另一个数组,它已经按照所需的排名系统排列,基于它们的索引。就像“ZYX....0”,X将被分配一个值为3。所以我想首先用其分配的值替换每个矩阵的第一列。从那里开始,我需要将列相乘并将所有结果相加。 - JTP
1
@JTP 请编辑您的问题,最好附上一些示例数据和结果。 - Adám
@Adám 我进行了编辑,希望有所帮助。 - JTP
@JTP 确实如此。我已相应更新了我的答案。 - Adám
@JTP 我已经绕过了访问每个矩阵元素的问题,但现在我添加了一个链接到解决该问题的问题 - Adám
1个回答

3

使用您的示例排列:

      ⎕ ← arranged ← ⌽ ⎕D , ⎕A
ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210

现在,我们可以获取索引值:
      1  m
XX11X1X
       1  m
X1
      arranged   1  m
3 35

虽然你可以先计算中间步骤,但是把大部分最终公式包含在Key操作数中会更简单:

      { ( arranged ⍳ ⍺ ) × 10 * ≢⍵ }⌸¨ ↓m
┌───────────┬───────────┬───────────┬─────────────────┬───────────────┐
│30000 35000│30000 28000│20000 36000│10000 290 280 270│26000 25000 240│
└───────────┴───────────┴───────────┴─────────────────┴───────────────┘

现在我们只需要对每个进行求和:
      +/¨ { ( arranged ⍳ ⍺ ) × 10 * ≢⍵ }⌸¨ ↓m
65000 58000 56000 10840 51240

实际上,我们可以将求和与键的应用结合起来,以避免双重循环:

      { +/ { ( arranged ⍳ ⍺ ) × 10 * ≢⍵ }⌸ ⍵}¨ ↓m
65000 58000 56000 10840 51240

为了完整起见,这里介绍一种使用中间结果的方法。让我们首先只处理第一个矩阵(你可以使用2⊃代替来获取第二个矩阵 - 有关详细信息,请参见在APL中使用数组时出现的问题。我错过了什么?):
      ⊃{⍺ (≢⍵)}⌸¨ ↓m
X 4
1 3

我们可以通过reduction在左列元素和右列元素之间插入一个函数:
      {⍺ 'foo' ⍵}/ ⊃{⍺ (≢⍵)}⌸¨ ↓m
┌─────────┬─────────┐
│┌─┬───┬─┐│┌─┬───┬─┐│
││X│foo│4│││1│foo│3││
│└─┴───┴─┘│└─┴───┴─┘│
└─────────┴─────────┘

现在我们只需要修改占位符函数,使其查找排列好的项目中的左参数,并乘以10的右参数次方即可:

      { ( arranged ⍳ ⍺ ) × 10 * ⍵ }/ ⊃{⍺ (≢⍵)}⌸¨ ↓m
30000 35000

我们不仅将其应用于第一个矩阵,还将其应用于每个矩阵:

      { ( arranged ⍳ ⍺ ) × 10 * ⍵ }/¨ {⍺ (≢⍵)}⌸¨ ↓m
┌───────────┬───────────┬───────────┬─────────────────┬───────────────┐
│30000 35000│30000 28000│20000 36000│10000 290 280 270│26000 25000 240│
└───────────┴───────────┴───────────┴─────────────────┴───────────────┘

现在我们只需要对每个进行求和:
      +/¨ { ( arranged ⍳ ⍺ ) × 10 * ⍵ }/¨ {⍺ (≢⍵)}⌸¨ ↓m
65000 58000 56000 10840 51240

然而,这是一种更加迂回的方法,仅供参考。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接