Estoy jugando con un ejemplo en https: //code.kx. com / q / ref / modify / # secciones transversales

$ 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]

Todo funciona bien, excepto si trato de hacer referencia a un solo elemento d [1; 1]:

q)i:(1 0; 0 1 0)
q)r:.[d; i; ,; y]
'type
  [0]  r:.[d; i; ,; y]

Pero si uso join , para listas y para un solo elemento, funciona como se supone:

q)10,200
10 200
q)10,((),200)
10 200

Entonces, ¿por qué la operación de modificación se rompe en esta unión simple?

Upd:

Un ejemplo más:

q)@[(1; 2; 3);1;,;10]
'type
  [0]  @[(1; 2; 3);1;,;10]
       ^

Pero está bien si uno usa listas:

q)@[(1; (),2; 3);1;,;10]
1
2 10
3
kdb
1
egor7 25 abr. 2020 a las 15:51

2 respuestas

La mejor respuesta

La respuesta está en examinar los datos que está extrayendo para unirse, aquí el operador -3! es su amigo para ayudar a revelar la estructura real a través de múltiples capas de alistamiento

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

No, aquí podemos ver que en el primer caso, cada elemento de r1 es una lista de listas, pero para r2 el primer elemento es 2 listas de longs con un long atómico 10.

De la documentación de la sección transversal

La forma de y es 2 3, la misma forma que la sección transversal seleccionada por d. yo

Es decir, la forma debe coincidir con los recuentos y los tipos, el tipo de cada elemento de y es un 7h, que debe coincidir con el tipo de cada selección de d.

Esencialmente, cuando utilice los operadores de enmienda , y @, esperará la conformidad, ya que está utilizando una enmienda en su lugar. a:1;a,:1 2 3 también fallará.

Podemos confirmar esto con sus otros ejemplos.

q)type @[(1; (),2; 3);1]
7h

Cambiar ese ejemplo para ajustar el primer elemento

q)@[(1; (),2; 3);0;,;10]
'type

La razón por la que solo usar el operador , como 10,((),200) no causó ningún error, es porque lo está usando fuera de las sobrecargas de enmienda, dentro de la sobrecarga de enmienda , se espera que funcione con forma a juego. Cuando se usa directamente, puede promover y ajustar la forma.

2
Callum Biggs 26 abr. 2020 a las 11:58

La única explicación que puedo ofrecer es que kdb + intenta usar la modificación en el lugar (también conocida como asignación a través del operador) cuando puede.

Por ejemplo, esto funciona:

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

Pero esto no:

q)l:(8 9;10;11 12)
q)l[1],:200
'type
[0]  l[1],:200
       ^

El último falla porque kdb no puede sustituir el vector 10 200 por el átomo 10: cambiar los tipos no es algo que modifique Se supone que el lugar debe hacer.

Si utilizó su propia función {x,y} en lugar del operador más , el segundo la expresión de su ejemplo también funcionaría como se esperaba porque kdb reemplazará los valores existentes con valores de retorno de la función (que, en contraste con el , incorporado, es un cuadro negro hasta ahora como kdb se refiere):

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)
2
Igor Korkhov 26 abr. 2020 a las 09:16