修改单个元素的横截面
Amend cross sections for single element
我正在玩 https://code.kx.com/q/ref/amend/#cross-sections
上的一个例子
$ q
KDB+ 3.6 2019.04.02 Copyright (C) 1993-2019 Kx Systems
q)d:((1 2 3;4 5 6 7);(8 9;10;11 12);(13 14;15 16 17 18;19 20))
q)i:(2 0; 0 1 0)
q)y:(100 200 300; 400 500 600)
q)r:.[d; i; ,; y]
一切正常,除非我尝试引用单个元素 d[1;1]:
q)i:(1 0; 0 1 0)
q)r:.[d; i; ,; y]
'type
[0] r:.[d; i; ,; y]
但是如果我对列表使用 join ,
并且只对单个元素使用它,它会按预期工作:
q)10,200
10 200
q)10,((),200)
10 200
那么为什么修改操作会在这个简单的连接上中断?
更新:
再举一个例子:
q)@[(1; 2; 3);1;,;10]
'type
[0] @[(1; 2; 3);1;,;10]
^
但如果使用列表就可以了:
q)@[(1; (),2; 3);1;,;10]
1
2 10
3
我能提供的唯一解释是 kdb+ 在可能的情况下尝试使用就地修改(也称为 assignment through the operator)。
例如,这个有效:
q)l:(13 14;15 16 17 18;19 20)
q)l[1],:200
q)l
13 14
15 16 17 18 200
19 20
但事实并非如此:
q)l:(8 9;10;11 12)
q)l[1],:200
'type
[0] l[1],:200
^
后者失败是因为 kdb 无法用 vector 10 200
替换 atom 10
- - 更改类型不是就地修改应该做的事情。
如果你使用自己的函数 {x,y}
而不是加号 运算符 第二个
您的示例中的表达式也将按预期工作,因为 kdb 将 replace 现有值与函数的 return 值(与内置 ,
, 就 kdb 而言是一个黑盒子):
q)i:(1 0; 0 1 0)
q)r:.[d; i; ,; y]
q).[d; ii; {x,y}; y]
(1 2 3 400 600;4 5 6 7 500)
(8 9 100 300;10 200;11 12)
(13 14;15 16 17 18;19 20)
答案在于检查您提取要加入的数据,这里运算符 -3!
是您的朋友,可帮助您通过多层征募揭示实际结构
q)d:((1 2 3;4 5 6 7);(8 9;10;11 12);(13 14;15 16 17 18;19 20))
q)i1:(2 0; 0 1 0)
q)i2:(1 0; 0 1 0)
q)y:(100 200 300; 400 500 600)
q)-3!r1:.[d; i1]
"((13 14;15 16 17 18;13 14);(1 2 3;4 5 6 7;1 2 3))"
q)q){type each x} each .[d; i1]
7 7 7
7 7 7
q)-3!r2:.[d; i2]
"((8 9;10;8 9);(1 2 3;4 5 6 7;1 2 3))"
q){type each x} each .[d; i2]
7 -7 7
7 7 7
不在这里我们可以看到,在第一种情况下,r1
的每个元素都是列表的列表,但对于 r2
,第一个元素是 2 个具有原子长 10
。
来自横截面文档
The shape of y is 2 3, the same shape as the cross-section selected by d . i
即Shape应该是计数和类型匹配,y的每一项的类型是一个7h,应该匹配d中每个选择的类型。
本质上,当您使用修正运算符 ,
和 @
时,它将期望符合性,因为它正在使用修正。 a:1;a,:1 2 3
也会失败。
我们可以用你的其他例子来证实这一点
q)type @[(1; (),2; 3);1]
7h
更改该示例以调整第一个元素
q)@[(1; (),2; 3);0;,;10]
'type
仅将 ,
运算符用作 10,((),200)
不会导致任何错误的原因是因为您在修改重载之外,在修改重载 ,
中使用它期望使用匹配的形状。直接使用可促进和调整形状。
我正在玩 https://code.kx.com/q/ref/amend/#cross-sections
上的一个例子$ q
KDB+ 3.6 2019.04.02 Copyright (C) 1993-2019 Kx Systems
q)d:((1 2 3;4 5 6 7);(8 9;10;11 12);(13 14;15 16 17 18;19 20))
q)i:(2 0; 0 1 0)
q)y:(100 200 300; 400 500 600)
q)r:.[d; i; ,; y]
一切正常,除非我尝试引用单个元素 d[1;1]:
q)i:(1 0; 0 1 0)
q)r:.[d; i; ,; y]
'type
[0] r:.[d; i; ,; y]
但是如果我对列表使用 join ,
并且只对单个元素使用它,它会按预期工作:
q)10,200
10 200
q)10,((),200)
10 200
那么为什么修改操作会在这个简单的连接上中断?
更新:
再举一个例子:
q)@[(1; 2; 3);1;,;10]
'type
[0] @[(1; 2; 3);1;,;10]
^
但如果使用列表就可以了:
q)@[(1; (),2; 3);1;,;10]
1
2 10
3
我能提供的唯一解释是 kdb+ 在可能的情况下尝试使用就地修改(也称为 assignment through the operator)。
例如,这个有效:
q)l:(13 14;15 16 17 18;19 20)
q)l[1],:200
q)l
13 14
15 16 17 18 200
19 20
但事实并非如此:
q)l:(8 9;10;11 12)
q)l[1],:200
'type
[0] l[1],:200
^
后者失败是因为 kdb 无法用 vector 10 200
替换 atom 10
- - 更改类型不是就地修改应该做的事情。
如果你使用自己的函数 {x,y}
而不是加号 运算符 第二个
您的示例中的表达式也将按预期工作,因为 kdb 将 replace 现有值与函数的 return 值(与内置 ,
, 就 kdb 而言是一个黑盒子):
q)i:(1 0; 0 1 0)
q)r:.[d; i; ,; y]
q).[d; ii; {x,y}; y]
(1 2 3 400 600;4 5 6 7 500)
(8 9 100 300;10 200;11 12)
(13 14;15 16 17 18;19 20)
答案在于检查您提取要加入的数据,这里运算符 -3!
是您的朋友,可帮助您通过多层征募揭示实际结构
q)d:((1 2 3;4 5 6 7);(8 9;10;11 12);(13 14;15 16 17 18;19 20))
q)i1:(2 0; 0 1 0)
q)i2:(1 0; 0 1 0)
q)y:(100 200 300; 400 500 600)
q)-3!r1:.[d; i1]
"((13 14;15 16 17 18;13 14);(1 2 3;4 5 6 7;1 2 3))"
q)q){type each x} each .[d; i1]
7 7 7
7 7 7
q)-3!r2:.[d; i2]
"((8 9;10;8 9);(1 2 3;4 5 6 7;1 2 3))"
q){type each x} each .[d; i2]
7 -7 7
7 7 7
不在这里我们可以看到,在第一种情况下,r1
的每个元素都是列表的列表,但对于 r2
,第一个元素是 2 个具有原子长 10
。
来自横截面文档
The shape of y is 2 3, the same shape as the cross-section selected by d . i
即Shape应该是计数和类型匹配,y的每一项的类型是一个7h,应该匹配d中每个选择的类型。
本质上,当您使用修正运算符 ,
和 @
时,它将期望符合性,因为它正在使用修正。 a:1;a,:1 2 3
也会失败。
我们可以用你的其他例子来证实这一点
q)type @[(1; (),2; 3);1]
7h
更改该示例以调整第一个元素
q)@[(1; (),2; 3);0;,;10]
'type
仅将 ,
运算符用作 10,((),200)
不会导致任何错误的原因是因为您在修改重载之外,在修改重载 ,
中使用它期望使用匹配的形状。直接使用可促进和调整形状。