j - 具有重复索引的数组的总和

标签 j

如何通过索引将一个数字数组添加到另一个数组?特别是对于重复索引。就这样

   x
1 2 3 4
  idx
0 1 0
   y
5 6 7
   ] x add idx;y NB. (1 + 5 + 7) , (2 + 6) , 3 , 4
13 8 3 4

所有名词(x、idx、y)都可以是数百万个项目,我需要快速“添加”动词。

更新

解决方案(感谢 Dan Bron):

   cumIdx =: 1 : 0
   :
   'i z' =. y
   n =. ~. i
   x n}~ (n{x) + i u//. z
   )
   (1 2 3 4) + cumIdx (0 1 0);(5 6 7)
13 8 3 4

最佳答案

现在,在“完成它”模式下的简短回答:

data   =.  1 2 3 4
idx    =.  0 1 0
updat  =.  5 6 7

cumIdx =:  adverb define
:
  n =. ~. m
  y n}~ (n{y) + m +//. x
)

  updat idx cumIdx data  NB. 13 8 3 4

简而言之:

  1. 首先对索引数组具有相同值的更新数组(在您的帖子中,y¹)进行分组,然后取每组的总和
    1. 使用 the adverb key 完成此操作(/.) 以 sum (+/) 作为其动词参数,派生一个二元动词,其参数为左边的 idx 和更新右边的数组(你的 y,我的 updat)。
  2. 获取索引数组的核心 (~.)
  3. 从您的值数组中选择这些(唯一的)索引(您的 x,我的 data)
    1. 根据定义,这将与我们在 (1.) 中计算的累积和具有相同的长度。
  4. 将这些添加到累计总和
  5. 现在您有了对数据的最终更新; updatidx 具有相同的长度,因此您只需使用 } 将它们合并到您的值数组中,就像您在代码中所做的那样

由于我们保持更新数组较小(永远不会大于其原始长度),因此这在较大的输入上应该有不错的性能,尽管我没有运行任何测试。唯一的性能缺陷是对 idx 的 nub 进行了双重计算(一次显式地使用 ~. 并且一次隐式地使用 /.),尽管因为你的值是整数,这应该比较便宜;在性能方面,这是 J 的强项之一。


¹ 我意识到重命名你的数组会使这个答案比它需要的更冗长。但是,由于您将主数据命名为 x 而不是 y(这是约定),如果我只是保留您的命名约定,那么当我调用 cumIdx ,定义内的名词名称将与定义外的名词具有相反的含义,我认为这会引起更大的混淆。因此,最好将“原始数据”放在右边 (y),将“control data”放在左边 (x)。

您还可以考虑限制使用特殊名称 xyuv ,mn 到它们已经通过调用显式定义隐式定义的地方;绝对不要更改他们的名称类。

关于j - 具有重复索引的数组的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69101709/

相关文章:

search - 在 J 中使用向量/矩阵时打印值及其关联索引

j - 一旦在默认情况下添加平方根,结果就会不同

j - 这个空列表的第一个元素怎么是0呢?

j - J中的二元钩子(Hook)有什么用吗?

j - `0".>,.2}.` 部分在 J 脚本中的作用是什么?

dice - K个N面骰子的不同掷数

j - 如何在 J/Jd 中加入截至时间序列

J 幂函数的语言等级

j - 将集合分成两个对

j - 如何将 J 中的相等值分组?