Классифицировать каждую строку на основе установленного количества интервалов в день в KDB? - PullRequest
1 голос
/ 05 июля 2019

С учетом следующей таблицы:

Исходная таблица:

shop | time    
-----------
  A  | 1000
  A  | 1100
  B  | 1130
  B  | 1131
  C  | 1132
  A  | 1133
  A  | 1134
  B  | 1230
  C  | 1232
  C  | 1400

Таблица результатов:

   shop | time |  mark  Number of times a shop has appeared within an interval.
   --------------------
 1)  A  | 1000 |   0    [A = 1]
 2)  A  | 1100 |   0    [A = 2]
 3)  B  | 1130 |   0    [A = 2, B = 1]
 4)  B  | 1131 |   0    [A = 2, B = 2]
 5)  C  | 1132 |   0    [A = 2, B = 2, C = 1]
 6)  A  | 1133 |   0    [A = 2, B = 2, C = 1]
 7)  A  | 1134 |   1    [A = 3 (Mark cell), B = 2, C = 1]
 8)  B  | 1230 |   1    [A = 1, B = 3 (Mark cell), C = 1]
 9)  C  | 1232 |   0    [A = 1, B = 1, C = 2]
10)  C  | 1400 |   0    [A = 1, B = 1, C = 0]

Где:

  • t = 1 час.

  • n = 3.

Для фиксированного интервала t, если в t или *1029* или больше транзакций, отметьте строку как true 1.Остальное пометить как 0.

Объяснение:

  • Строки с 1 по 2, A совершает две транзакции в пределах t.

  • Строки с 3 по 4, B совершает две транзакции в течение t.

  • Строка 5, C имеет первую транзакцию.

  • Строка 6, A выполняет другую транзакцию, но ячейка не помечается, поскольку интервал - между этой и первой транзакцией превышает t(1000 -> 1133).

  • Строка 7, строка помечена как A , имеет n транзакцию в пределах t (1100 -> 1133 -> 1134).

  • Строка 8, строка помечена как B , имеет n транзакцию в пределах t (1130 -> 1131 -> 1230)

  • Строка 9 и 10, C выполняет две транзакции, но не отмечена, поскольку интервал превышает t (1132 -> 1232 ---> 1400)

Кроме того, он будет обновляться на ежедневной основе (столбец DealDate включен в форматt YYYYMMDD)

По сути, это эмулировало очередь для каждого магазина, в которой каждый предмет, помещенный в стек, будет отмечен в зависимости от количества предметов в очереди, причем каждый последний предмет превышает интервалpopped.

Как я могу сделать это в KDB только с помощью Q?Даты и метки времени упорядочены в порядке убывания.

1 Ответ

6 голосов
/ 05 июля 2019

Вы можете использовать:

q)table:([]shop:`A`A`B`B`C`A`A`B`C`C; time:1000 1100 1130 1131 1132 1133 1134 1230 1232 1400)
q)t:100
q)n:3
q)update mark:t>=(t+1)^time-(n-1)xprev time by shop from table
shop time mark
--------------
A    1000 0
A    1100 0
B    1130 0
B    1131 0
C    1132 0
A    1133 0
A    1134 1
B    1230 1
C    1232 0
C    1400 0

Это вычисляет разницу во времени между каждой ячейкой и ячейкой, которая произошла в двух строках позади нее (time-(n-1)xprev time) для этого магазина (by shop).

Затем он заполняет нули значением больше t, поскольку мы не хотим включать эти ячейки ((t+1)^).

Затем он проверяет, находится ли самое раннее время из трех в пределах 1 часа от текущего времени, присваивая 1, где это правда (t>=).

Это также может быть обновлено для каждой даты, включая by dealDate:

table:([]dealDate:(10#20190704),10#20190705;shop:20#`A`A`B`B`C`A`A`B`C`C; time:20#1000 1100 1130 1131 1132 1133 1134 1230 1232 1400)
q)update mark:t>=(t+1)^time-(n-1)xprev time by dealDate,shop from table
dealDate shop time mark
-----------------------
20190704 A    1000 0
20190704 A    1100 0
20190704 B    1130 0
20190704 B    1131 0
20190704 C    1132 0
20190704 A    1133 0
20190704 A    1134 1
20190704 B    1230 1
20190704 C    1232 0
20190704 C    1400 0
20190705 A    1000 0
20190705 A    1100 0
20190705 B    1130 0
20190705 B    1131 0
20190705 C    1132 0
20190705 A    1133 0
20190705 A    1134 1
20190705 B    1230 1
20190705 C    1232 0
20190705 C    1400 0

Возможно, вы захотите, чтобы ваш столбец dealDate имел формат даты, а не YYYYMMDD, так как YYYYMMDD будет длинным. Например, вы можете изменить 20190705, приведя его к данным 2019.07.05, используя "D"$string 20190705

...