如何访问盒装数组的第n列?

时间:2013-01-28 11:07:45

标签: arrays j

鉴于我有一个形状为4 3

的盒装数组
v =. 4 3$'x1'; 'y1'; 'z1'; 'x2'; 'y2'; 'z2'; 'x3'; 'y3'; 'z3'
v
NB. +--+--+--+
NB. |x1|y1|z1|
NB. +--+--+--+
NB. |x2|y2|z2|
NB. +--+--+--+
NB. |x3|y3|z3|
NB. +--+--+--+
NB. |x1|y1|z1|
NB. +--+--+--+

选择

我可以通过1{::v

获取第二行
1{::v
NB. Get the second row
NB. +--+--+--+
NB. |x2|y2|z2|
NB. +--+--+--+

投影

但是如何访问第二列?

NB. Get the second column
NB. +--+
NB. |y1|
NB. +--+
NB. |y2|
NB. +--+
NB. |y3|
NB. +--+
NB. |y1|
NB. +--+

3 个答案:

答案 0 :(得分:5)

您还可以使用{指定等级"

1 {"1 v
NB. +--+--+--+--+
NB. |y1|y2|y3|y4|
NB. +--+--+--+--+

这将为您提供第二列,减去排名,因此只是一个形状4的数组。要使其成形4 1,请使用Ravel项目,.

,.1 {"1 v
NB. +--+
NB. |y1|
NB. +--+
NB. |y2|
NB. +--+
NB. |y3|
NB. +--+
NB. |y1|
NB. +--+

此外,所有这些逻辑都适用于矩阵是否装箱。

答案 1 :(得分:3)

正如其他海报所观察到的那样,J中的阵列访问被加权到主(前导)轴。也就是说,J语言可以很容易地沿着数组的长度(第一项,第二项,第三项等)寻址元素。

要访问非引导轴,J程序员通常会采用两种策略中的一种,分别由abstraktor和MPelletier的响应证明:

  • 更改数组,使感兴趣的轴实际上成为的引导轴;在您的情况下,通过将第二个(“列”)轴转换为第一个(“行”)轴,如使用|:在abstraktor的解决方案中所示。

  • 或者更改访问者函数的透视图,以便感兴趣的轴从该访问者的角度看起来像的前导轴。这可以通过MPelletier的解决方案来说明,该解决方案使用rank({)更改"(在您的情况下是访问者函数)的视角。在他的例子中,{的POV一次限制为一行,所以现在从该函数的角度来看,前导轴是每行的原子 - 当时聚合,对应列(当然)。

因此,这些是访问J中非引导轴的主要方法。尽管如此,某些原始函数实际上可以直接处理非引导轴。事实上,{就是其中之一,如果你正确地格式化它的参数:

   (<a:;1) { v
+--+--+--+--+
|y1|y2|y3|y1|
+--+--+--+--+

在这里,我们将盒装左参数传递给{。当我们这样做时,{理解该框本身包含一个框列表:每个轴一个框(形状中的项)右边的参数。这些(子)框中的每一个将指示右参数的对应轴的选择标准。这里,我们使用“a:”来表示第一轴的“a”ll,使用1表示第二轴的第二个元素(即第二列)。我们也可以混合搭配,例如“第二行和第三行的第一列和最后一列”:

   (<1 2;0 _1) { v
+--+--+
|x2|z2|
+--+--+
|x3|z3|
+--+--+

当然,这会以显而易见的方式扩展到N维数组。

因此,您可以使用{直接处理数组的非引导轴。某些其他基元共享此功能,但当然它们仍然在寻址轴上执行其定义的功能(因此,如果您只想选择数据,请使用{)。

假设您希望将数组剪切(分区)为列,而不是更常用的行。然后你可以使用;. cut ),但是用一个盒装的左手参数代替通常的开放LHA:

   ('';1) <;.1 v
+----+----+----+
|+--+|+--+|+--+|
||x1|||y1|||z1||
|+--+|+--+|+--+|
||x2|||y2|||z2||
|+--+|+--+|+--+|
||x3|||y3|||z3||
|+--+|+--+|+--+|
||x1|||y1|||z1||
|+--+|+--+|+--+|
+----+----+----+

实际上,我们可以使用这种方法同时处理多个轴;例如,我们可以将数组分组为每列分割的行对(即分成2x1个子阵列):

   (1 0 1 0;1) <;.1 v
+----+----+----+
|+--+|+--+|+--+|
||x1|||y1|||z1||
|+--+|+--+|+--+|
||x2|||y2|||z2||
|+--+|+--+|+--+|
+----+----+----+
|+--+|+--+|+--+|
||x3|||y3|||z3||
|+--+|+--+|+--+|
||x1|||y1|||z1||
|+--+|+--+|+--+|
+----+----+----+

或者,让我们说不是选择列,而是想要丢掉一些。然后你可以使用}. drop )和矢量LHA而不是通常的标量:

   0 1 }. v  NB. Keep all the rows but drop the first column
+--+--+
|y1|z1|
+--+--+
|y2|z2|
+--+--+
|y3|z3|
+--+--+
|y1|z1|
+--+--+


   2 _1 }. v  NB. drop the first two rows and the last column
+--+--+
|x3|y3|
+--+--+
|x1|y1|
+--+--+

同样适用于{.拍摄):

   _ 1 {. v   NB. Take all the rows (_=∞) but only 1 column (the first)
+--+
|x1|
+--+
|x2|
+--+
|x3|
+--+
|x1|
+--+

同样,|. rotate )的矢量LHA允许我们来回旋转数组的任何维度(或维度):_2 |. vv两行的行旋转,而0 1 |. v旋转一个位置(向后),_2 1 |. v将两者都旋转(所以左上角)角落将是“y3”)。

矢量LHA还允许转置处理任何轴的集合,并将它们全部移动到阵列的后面(即转置它们):

   $ 1 2 |: i. 11 22 33 44  NB.  Transpose the middle dimensions to the end
11 44 22 33
   $ 1 2 0 3 |: i. 11 22 33 44  NB. Mix up all dimensions
22 33 11 44

等。

总之,J语言旨在简化“主轴”(即第一个)的讨论,因为在实践中这是最常见的用例。要谈论短轴,通常你要么物理地翻转阵列(使用|:)将感兴趣的轴放在前面,要么你将修改你的函数的视角(使用")从该函数的角度来看,具有相同的效果。

此外,如果需要,J提供某些内置工具来直接处理非引导轴,如上所述。

注意:为了使示例简单,前面的讨论使用了单词“感兴趣的轴”这个短语。但鉴于J的面向数组的性质,使用短语“感兴趣的axE”(复数)会更精确。从这个意义上说,可以对散文和给出的例子进行单数替换,而不失一般性(事实上,获得它:语言鼓励在数组中思考,即同时在多个维度方面)。

答案 2 :(得分:2)

投影是转置矩阵的选择

  1. 使用|:转置
  2. 使用1{::
  3. 选择第二个(以前的列)
  4. 再次将结果重新整理为4 1$为垂直结果
  5. 总而言之

    4 1$1{::|:v
    NB. Get the second column
    NB. +--+
    NB. |y1|
    NB. +--+
    NB. |y2|
    NB. +--+
    NB. |y3|
    NB. +--+
    NB. |y1|
    NB. +--+