вызвать функцию с кратным значением kdb \ q - PullRequest
0 голосов
/ 29 июня 2018

У меня есть объявление функции:

func:{[id;time] select last synp from synp_t where instr_id = id, tp_time < time}

, где instr_id имеет тип i, а tp_time имеет тип v.

Например, func[8;05:00:11] работает нормально и дает мне значение 17.55.

Однако, если я попытаюсь func[8 1;05:00:11 07:10:59], я получу:

'length ERROR: incompatible lengths (different lengths of operands for synchronized operation or table columns lengths are not the same

То, что я хочу получить, это, например, 17.55 9.66.

Та же ошибка появится, если я сделаю select res:func_demo[id;time]from tab, где tab - таблица с двумя столбцами instr_id и tp_time.

Я думаю, enlist может решить проблему, но я не знаю точно, как ее использовать. Как я мог решить эту проблему?

Ответы [ 3 ]

0 голосов
/ 29 июня 2018

Я рекомендую использовать aj, чтобы получить результаты, глядя на ваш запрос, похоже, что вам нужна последняя цена для данного id и меньше, чем входное значение time.

q)func:{[id;time] aj[`instr_id`tp_time; ([] instr_id:id;tp_time: time);synp_t]}
q)func[1 1 2;05:00:11 07:10:59 10:10:00]

с each-both Вы вызываете функцию n раз и выбираете данные n раз. aj является одной из мощных функций Kdb обеспечивает asof цены.

На самом деле вам не нужна функция func, вы можете напрямую получить результаты, используя aj.

aj[`instr_id`tp_time; update instr_id:id, tp_time: time from tab;synp_t]
0 голосов
/ 29 июня 2018

Оба ответа здесь замечательные, но не дают подробных сведений о том, почему вы получили ошибку 'length. Ошибка была полностью в вашем where предложении where instr_id = id, tp_time < time. Когда вы передали список элементов, вы фактически создали список логических списков, которые передаются предложению where. Настройка двух примеров списков, чтобы выделить это:

q)show instr_id:-5?10
2 8 0 1 6
q)show tp_time:5?.z.t
01:05:42.696 03:42:39.320 17:44:49.101 15:01:01.470 05:47:49.777

Выполнение вашего первого условия instr_id = id с атомами и списками:

q)instr_id=2
10000b
q)instr_id=2 8
'length
  [0]  instr_id=2 8
               ^

Использование = будет работать только для атома списка равной длины instr_id. Если вы хотите передать несколько элементов в соответствие, вы можете вместо этого использовать in:

q)instr_id in 2
10000b
q)instr_id in 2 8
11000b

Для второго условия tp_time < time снова требуется передать атомы или списки одинаковой длины:

q)tp_time<.z.t
11111b
q)tp_time<.z.t,.z.t
'length
  [0]  tp_time<.z.t,.z.t
              ^

Можно обойти это, используя наречия, такие как по-правому /:, чтобы сравнить tp_time с несколькими элементами, и используя any, чтобы сократить его до одного списка:

q)tp_time</:.z.t,.z.t
11111b
11111b
q)any tp_time</:.z.t,.z.t
11111b

Надеюсь, это поможет вам понять, где вы столкнулись с вышеуказанными проблемами.

0 голосов
/ 29 июня 2018

func'[8 1;05:00:11 07:10:59] должно работать

Он использует каждое наречие, которое будет применять функцию между соответствующими элементами двух входных списков

Более подробную информацию о наречиях можно найти здесь http://code.kx.com/q/ref/adverbs/. Они очень мощные.

Многие встроенные функции могут принимать атомы и списки в качестве входных данных и работать соответственно, но с пользовательскими функциями вам, скорее всего, придется использовать наречия, чтобы использовать их в различных ситуациях

...