iter 函数超过 table 作为输入 - 顺序重要吗?为什么?
iter function over table as input - does order matter and why?
我是 kdb+/q 的新手,我发现下面的这个问题让我很困惑。只是为了简化,我们说我们有这个单行函数 f
returns 一个带有预设值的单行 table,我想 运行 这个函数的组合输入 x 和 y,例如日期(列表)和元数据(table,包含 orderid、px、大小等列)。
现在,我在下面列出了两种方法。由于函数 f
并没有真正使用任何输入,我认为 x
和 y
的顺序无关紧要,因为区别只是传递给 f
在另一个之前并且只有当两个输入通过时才会 f
开始运行。
但为什么我在第二种方式中出错,即 table 跟随列表?
非常感谢任何想法和解释。
f: {[x;y]
([] m: enlist `M; n: enlist `N)
};
x: 1 2 3;
y: ([] a: 4 5 6; b: 7 8 9);
raze raze f ' [y] ' [x]; // this one works
raze raze f ' [x] ' [y]; // this one gives ERROR: length Explanation: Arguments do not conform
你所做的实际上等同于:
f:{y;1};
q)(f'[([]a:1 2 3;b:4 5 3)])@/:1 2 3
1 1 1
1 1 1
1 1 1
(使用额外的括号来明确操作顺序)。
在这种情况下,每个都减少到
q)f'[([]a:1 2 3;b:4 5 3);1]
1 1 1
q)f'[([]a:1 2 3;b:4 5 3);2]
1 1 1
q)f'[([]a:1 2 3;b:4 5 3);3]
1 1 1
这里的“length”没问题,因为“y”值是原子的,kdb 会自动扩展这些原子值以匹配 table 的长度。换句话说,kdb 将这些视为:
q)f'[([]a:1 2 3;b:4 5 3);1 1 1]
1 1 1
q)f'[([]a:1 2 3;b:4 5 3);2 2 2]
1 1 1
q)f'[([]a:1 2 3;b:4 5 3);3 3 3]
1 1 1
但是,当您更改顺序时,它会变成:
(f'[1 2 3])@/:([]a:1 2 3;b:4 5 3)
相当于:
f'[1 2 3;`a`b!1 4]
f'[1 2 3;`a`b!2 5]
f'[1 2 3;`a`b!3 3]
但现在您确实遇到了长度问题,因为“y”变量中的字典不是原子的,它们的长度为 2。这与列表 (3) 的长度不匹配。
你没有这么说,但看起来你正在研究如何在列表参数上迭代二元函数 f
,这使你将 f'
投影到 x
,它给你一个一元 f'[x]
然后你迭代 y
。如果这就是我们到达这里的方式,您想要的可能就像 x f'y
一样简单,它在 x
和 y
.
中的相应项目上迭代 f
但是,您提到了 组合 输入。如果您想要有效地基于 f
的笛卡尔积,则组合迭代器 Each Right and Each Left 以获得 x f:/:\:y
.
即returns一个矩阵。你已经把你的结果夷为平地了。根据您的参数类型,您可以使用 cross
to generate all the argument pair combinations, and Apply Each .'
将 f
应用于每对:
f .' x cross y
我是 kdb+/q 的新手,我发现下面的这个问题让我很困惑。只是为了简化,我们说我们有这个单行函数 f
returns 一个带有预设值的单行 table,我想 运行 这个函数的组合输入 x 和 y,例如日期(列表)和元数据(table,包含 orderid、px、大小等列)。
现在,我在下面列出了两种方法。由于函数 f
并没有真正使用任何输入,我认为 x
和 y
的顺序无关紧要,因为区别只是传递给 f
在另一个之前并且只有当两个输入通过时才会 f
开始运行。
但为什么我在第二种方式中出错,即 table 跟随列表?
非常感谢任何想法和解释。
f: {[x;y]
([] m: enlist `M; n: enlist `N)
};
x: 1 2 3;
y: ([] a: 4 5 6; b: 7 8 9);
raze raze f ' [y] ' [x]; // this one works
raze raze f ' [x] ' [y]; // this one gives ERROR: length Explanation: Arguments do not conform
你所做的实际上等同于:
f:{y;1};
q)(f'[([]a:1 2 3;b:4 5 3)])@/:1 2 3
1 1 1
1 1 1
1 1 1
(使用额外的括号来明确操作顺序)。 在这种情况下,每个都减少到
q)f'[([]a:1 2 3;b:4 5 3);1]
1 1 1
q)f'[([]a:1 2 3;b:4 5 3);2]
1 1 1
q)f'[([]a:1 2 3;b:4 5 3);3]
1 1 1
这里的“length”没问题,因为“y”值是原子的,kdb 会自动扩展这些原子值以匹配 table 的长度。换句话说,kdb 将这些视为:
q)f'[([]a:1 2 3;b:4 5 3);1 1 1]
1 1 1
q)f'[([]a:1 2 3;b:4 5 3);2 2 2]
1 1 1
q)f'[([]a:1 2 3;b:4 5 3);3 3 3]
1 1 1
但是,当您更改顺序时,它会变成:
(f'[1 2 3])@/:([]a:1 2 3;b:4 5 3)
相当于:
f'[1 2 3;`a`b!1 4]
f'[1 2 3;`a`b!2 5]
f'[1 2 3;`a`b!3 3]
但现在您确实遇到了长度问题,因为“y”变量中的字典不是原子的,它们的长度为 2。这与列表 (3) 的长度不匹配。
你没有这么说,但看起来你正在研究如何在列表参数上迭代二元函数 f
,这使你将 f'
投影到 x
,它给你一个一元 f'[x]
然后你迭代 y
。如果这就是我们到达这里的方式,您想要的可能就像 x f'y
一样简单,它在 x
和 y
.
f
但是,您提到了 组合 输入。如果您想要有效地基于 f
的笛卡尔积,则组合迭代器 Each Right and Each Left 以获得 x f:/:\:y
.
即returns一个矩阵。你已经把你的结果夷为平地了。根据您的参数类型,您可以使用 cross
to generate all the argument pair combinations, and Apply Each .'
将 f
应用于每对:
f .' x cross y