gpt4 book ai didi

j - J 中的链式动词

转载 作者:行者123 更新时间:2023-12-04 14:50:33 32 4
gpt4 key购买 nike

假设一个包含各种类型的盒装矩阵:

matrix =: ('abc';'defgh';23),:('foo';'bar';45)
matrix
+---+-----+--+|abc|defgh|23|+---+-----+--+|foo|bar  |45|+---+-----+--+

And a column descriptor:

columnTypes =: 'string';'string';'num'

我想根据类型按列在这个矩阵上应用动词。我将使用动词 DoString 和 DoNum:
chain =: (('string';'num') i. columnTypes) { DoString`DoNum

编辑:列描述符很重要,决定使用哪个动词是基于它们, 不在类型本身 .实际上,我可以有多种类型的字符串、数字,甚至日期(在 J 中可能是数字)。

我如何申请 chainmatrix 的每一行?动词本身可以处理传递的值是否装箱,这很好。另外,我宁愿避免转置矩阵( |: ),因为它可能非常大。

最佳答案

执行此操作的标准方法是:

  • 将面向行(单元格)的结构转换为面向列的结构
  • 将正确的动词应用于每一列(仅一次)

  • 步骤(1)很简单。步骤 (2) 也很简单,但并不那么明显。有一个小技巧可以帮助。

    诀窍是知道许多原始运算符接受动名词作为左参数并产生一个在动名词上循环的函数,依次应用每个动词。 IMO,该类别中最有用的运算符是 ;. .这是使用它的示例实现:

    步骤(0),输入:
       matrix      =:  ('abc';'defgh';23),:('foo';'bar';45)

    columnTypes =: 'string';'string';'num'

    DoString =: toupper
    DoNum =: 0&j.

    matrix
    +---+-----+--+
    |abc|defgh|23|
    +---+-----+--+
    |foo|bar |45|
    +---+-----+--+

    步骤(1),整理数据:
       columnify   =:  <@:>"1@:|: :. rowify =: <"_1&>
    columnify matrix
    +---+-----+-----+
    |abc|defgh|23 45|
    |foo|bar | |
    +---+-----+-----+

    请注意, columnify 提供了一个反向,它将重新“行化”数据,尽管您不应该这样做:见下文。

    步骤 (2),使用 ;. 的动词循环功能,将正确的动词应用于每一列(恰好一次)。 :
       homogenize  =:  ({. foo&.>@:{.`'') [^:('foo'-:])L:0~ ]
    chain =: DoString`DoNum`] homogenize@{~ ('string';'num')&i.

    请注意,未知列类型的默认转换是恒等函数, ] .

    动词 homogenize标准化每个列处理器的输入和输出(即抽象出预处理和后处理,以便用户只需要提供转换的动态“核心”)。动词 chain将列类型列表作为输入并派生适合使用左侧参数的动名词 ;. (或类似的运营商)。

    因此:
       1 (chain columnTypes);.1  columnify matrix
    +---+-----+---------+
    |ABC|DEFGH|0j23 0j45|
    |FOO|BAR | |
    +---+-----+---------+

    或者,如果您真的必须有一个 NxM 的盒装单元格表,请应用“下”列化:
       1 (chain columnTypes);.1&.columnify matrix
    +-----+-----+
    |ABC |FOO |
    +-----+-----+
    |DEFGH|BAR |
    +-----+-----+
    |0j23 |0j45 |
    +-----+-----+

    但请注意 在 J 上下文中,出于性能和符号原因,将表保留为同类列的列表更为合适。

    J 在“全部”处理数组时效果最佳;经验法则是您应该让原始名称或用户定义的名称在每个应用程序中看到尽可能多的数据。这是这种“聚合”方法的主要好处:如果您将数据存储为同构列的列表,那么以后操作起来会更快更容易。

    但是,如果您的用例确实要求您将数据保存为 NxM 盒装单元格表,那么将您的数据转换为列标准形式和从列标准形式转换是一项代价高昂的空操作。在这种情况下,你应该坚持你原来的解决方案,
       1 chain\"1 matrix

    它(因为你问过)实际上与 ;. 在相同的前提下工作方法。特别是 \是另一种接受动名词参数的原始运算符,并连续应用每个动词(即循环应用到每个新的数据窗口)。

    实际上,什么 1 chain\"1 matrix确实是将矩阵分成行( "1 ),并且对于每一行,它创建一个 1 宽的移动窗口( 1 f\ matrix ),应用 chain 的动词循环到这些 1 宽窗口中的每一个(即 f 随矩阵每一行的每个 1 宽数据窗口而变化)。

    由于一行的移动 1-window(一个 rank-1 向量)是该行的原子,按顺序,以及 chain 的动词以相同的顺序给出,实际上您将这些动词应用于矩阵的列, 一。原子。在。一种。时间。

    简而言之: 1 chain\"1 matrix类似于 foo"0 matrix , 除了每个原子的 foo 变化。出于同样的原因,应该避免使用 foo"0 matrix一般应该避免:因为在小级别应用函数会违背 J 的粒度,从而导致性能损失。

    一般来说,最好尽可能使用更高级别的应用函数,在这种情况下需要转换(和维护) matrix到列范式。

    换句话说,这里, ;.是到 "1\是到 "0 .如果你找到整个 columnify/ homogenize东西太长或太笨重(与 1 chain\"1 matrix 相比),您可以导入 [1] 中提供的脚本,它将这些定义打包为可重用的实用程序,并带有扩展名。有关示例和说明,请参阅页面。

    [1] 相关实用程序脚本:
    http://www.jsoftware.com/jwiki/DanBron/Snippets/DOOG

    关于j - J 中的链式动词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6905439/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com