执行此操作的标准方法是:
将面向行(单元格)的结构转换为面向列的结构
对每一列应用正确的动词(仅一次)
步骤 (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 在“in toto”处理数组时效果最好;经验法则是您应该让原始名称或用户定义名称在每个应用程序中看到尽可能多的数据。这就是这种“columificaton”方法的主要好处:如果您将数据存储为同质列的列表,以后操作起来会更快、更容易。
但是,如果您的用例确实需要将数据保存为 NxM 盒装单元格表,那么将数据转换为列范式和从列范式转换是一项昂贵的空操作。在这种情况下,您应该坚持原来的解决方案,
1 chain\"1 matrix
哪个(因为你问过)实际上与;. 方法在相同的前提下工作。特别是,\ 是另一个接受动名词参数并连续应用每个动词(即循环地应用于每个新的数据窗口)的原始运算符。
实际上,1 chain\"1 matrix 所做的是将矩阵分成几行 ("1),并为每一行创建一个宽度为 1 的移动窗口 (1 f\ matrix),应用 chain 的动词循环到每个 1 宽的窗口(即f 随矩阵每一行的每个 1 宽的数据窗口而变化)。
由于行的移动 1 窗口(rank-1 向量)是该行的原子,按顺序排列,并且chain 的动词以相同的顺序给出,实际上您正在应用这些矩阵列的动词,one。原子。在。一个。时间。
简而言之: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