kdb q - создать 2d корзины для натуральных чисел - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь создать 2-мерные сегменты в q

. При заданной 2-мерной сетке

5 o---o---o
  |   |   |
3 o---o---o
  |   |   |
0 o---o---o
  0   3   5

каждый узел в сетке определяет границу 2-мерных сегментов для натуральных чисел.Например, центральный узел будет содержать кортежи (x;y), где 3<=x<5 и 3<=y<5.Девять сегментов индексируются из 0,...,8.

Я пытался реализовать это в q как

bucketidx:{((0 3 5i) cross (0 3 5i)) bin "i"$(first x;last x)}

Чтобы пройти через сегменты:

bucketidx each ((0 3 5i) cross (0 3 5i))
/0j, 1j, 2j, 3j, 4j, 5j, 6j, 7j, 8j

Однако я получаю странное поведение на bucketidx 6 0.Я ожидаю, что это будет в верхнем левом узле

(5<=y) and (x=0)

, но он возвращает индекс 8, который будет верхним правым узлом.Надеюсь, понятно, что я пытаюсь сделать.

Спасибо за помощь

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

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

q)d:`s#0 3 5!0 1 2
q)3 sv' d@(0 3 5i) cross (0 3 5i)
0 1 2 3 4 5 6 7 8
q)3 sv' d@enlist 6 0
,6
0 голосов
/ 12 декабря 2018

Это из-за поведения корзины.

Двоичный поиск возвращает индекс последнего элемента в x, который равен <= y </p>

https://code.kx.com/q/ref/search/#bin-binr

Ваш список:

    q) a:(0 3 5i) cross (0 3 5i)
    q) a / (0 0; 0 3;0 5;3 0; 3 3; 3 5;5 0;5 3; 5 5)

Вы ищете (6 0) в этом списке, используя функцию bin, и последний элемент в этом списке, который равен <= (6; 0), равен (5; 5), и индекс этого элемента равен8. </p>

    q) a bin 6 0 / 8

Вот почему вы получаете 8.

Я думаю, что подход «кортеж с бином» не является правильным способом решения этой проблемы.

Вы можете использовать что-то похожее на идею ниже.Первый аргумент функции - это координата X, а второй - координата Y.

 q) node:{b:0 3 5;(b bin x)+3*b bin y}
 q) node[0;6] / 6
...