列的条件更新
Conditional update of column
我有一笔交易 table 由日期、时间、代码、交易量、收盘竞价交易量组成。
不幸的是,收盘拍卖量包括在 table 的最后一个箱子中,并且使事情复杂化的可能是在半天内的 15:59:00 或 12:59:00。
有没有办法有条件地更新成交量来移除收盘成交量?
例如,如果它存在,则从 15:59:00 的卷中将其删除,否则将其从 12:59:00 的卷中删除。
例如
t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02;time:12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL;volume:100 25000 26000 0; closingvol: 24000 24000 21000 21000)
**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|15:59:00|AAPL|25000|24000
2019-02-02|12:59:00|AAPL|26000|21000
2019-02-02|15:59:00|AAPL|0|21000
我想成为
**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-02|12:59:00|AAPL|5000|21000
2019-02-02|15:59:00|AAPL|0|21000
我希望我可以避开下面的问题,但是 "or" 的行为似乎不像我希望的那样,因为它从不修改第二个 12:59:00 条目。
update volume:volume-closingvol from t where (time=15:59:00 | time=12:59:00), volume>=closingvol
**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-02|12:59:00|AAPL|26000|21000
2019-02-02|15:59:00|AAPL|0|21000
** 更新 1**
按照建议我也试过了:
更新 volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00, volume>=closingvol
例如如下所示,所有卷都已更新。我本来预计在 2019.02.01 只更新 AAPL 的 15:59:00 和 BAC 的 12:59:00,而在 2019.02.02 只更新 BAC 的 15:59:00 和 12:59:00 对于 AAPL,但这修改了 12:59:00 和 15:59:00.
的所有实例
t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02 2019.02.02 2019.02.02 2019.02.01 2019.02.01;time:12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL`BAC`BAC`BAC`BAC;volume:100 25000 26000 0 20000 12000 13000 0; closingvol: 24000 24000 21000 21000 11000 11000 12000 12000)
t:`date`time xasc t
update volume:volume-closingvol from t where (time=15:59:00)|(time=12:59:00), volume>=closingvol
**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|12:59:00|BAC|1000|12000
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-01|15:59:00|BAC|0|12000
2019-02-02|12:59:00|AAPL|5000|21000
2019-02-02|12:59:00|BAC|9000|11000
2019-02-02|15:59:00|AAPL|0|21000
2019-02-02|15:59:00|BAC|1000|11000
目前,当 q 从右到左评估 where 子句中的每个约束时,会发生以下情况:
q)time:12:59:00 15:59:00 12:59:00 15:59:00
q)15:59:00 | time=12:59:00
15:59:00 15:59:00 15:59:00 15:59:00
|在这种情况下表现得像最大值:
http://code.kx.com/q/ref/arith-integer/#or-maximum
只需更改括号的位置:
q)update volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00, volume>=closingvol
date time sym volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100 24000
2019.02.01 15:59:00 AAPL 1000 24000
2019.02.02 12:59:00 AAPL 5000 21000
2019.02.02 15:59:00 AAPL 0 21000
为次要示例编辑 -
您可以利用 fby (http://code.kx.com/q/ref/qsql/#fby),这将允许您添加额外的约束,为每个 [=25] 更新最大记录(时间 12:59 或 15:59) =]:
q)update volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00,volume>=closingvol,time=(max;time)fby ([]date;sym)
date time sym volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100 24000
2019.02.01 12:59:00 BAC 1000 12000
2019.02.01 15:59:00 AAPL 1000 24000
2019.02.01 15:59:00 BAC 0 12000
2019.02.02 12:59:00 AAPL 5000 21000
2019.02.02 12:59:00 BAC 20000 11000
2019.02.02 15:59:00 AAPL 0 21000
2019.02.02 15:59:00 BAC 1000 11000
vector conditional ?
在这里可能会有用:
update volume:?[time in 12:59:00 15:59:00;volume-closingvol;volume] from t where vol>=closingvol
第一个参数需要一个布尔列表 - 由 time in 12:59:00 15:59:00
检查创建,并应用第一个条件(删除 closingvol),其中此列表 returns 为真,否则应用第二个条件(离开原样的音量)。
您的示例表明对于同一日期,sym 对,两次交易量都可能大于收盘量 - (12:59:00 15:59:00)。这就是条件 'vol>=closingvol' 给出错误答案的原因(您在您的示例中使用了该答案,也用于您的 post 的其他答案)。
以下解决方案将基于以下假设工作:
- 所有日期、符号组合都有两个时间 - (12:59:00 15:59:00)。
- 数据按时间排序。
即使上述假设在实际场景中不成立,也很容易更改以下查询以根据该假设工作。
q) t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02 2019.02.02 2019.02.02 2019.02.01 2019.02.01;time:12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL`BAC`BAC`BAC`BAC;volume:100 25000 26000 0 20000 12000 13000 0; closingvol: 24000 24000 21000 21000 11000 11000 12000 12000)
q) update volume:{?[0=x 1;(x[0]-y[0]),x 1;x[0],x[1]-y[1]]}[volume;closingvol] by date,sym from t where time in (12:59:00 15:59:00)
或同一查询的其他版本:
q) update volume: volume-closingvol*(0 1;1 0)0=volume 1 by date,sym from t where time in (12:59:00 15:59:00)
date time sym volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100 24000
2019.02.01 15:59:00 AAPL 1000 24000
2019.02.02 12:59:00 AAPL 5000 21000
2019.02.02 15:59:00 AAPL 0 21000
2019.02.02 12:59:00 BAC 20000 11000
2019.02.02 15:59:00 BAC 1000 11000
2019.02.01 12:59:00 BAC 1000 12000
2019.02.01 15:59:00 BAC 0 12000
您还可以通过将 x 和 y 替换为 volume 和 closingvol 来避免查询中的 lambda 函数。我用这种方法让它变小了一点。
我有一笔交易 table 由日期、时间、代码、交易量、收盘竞价交易量组成。
不幸的是,收盘拍卖量包括在 table 的最后一个箱子中,并且使事情复杂化的可能是在半天内的 15:59:00 或 12:59:00。
有没有办法有条件地更新成交量来移除收盘成交量?
例如,如果它存在,则从 15:59:00 的卷中将其删除,否则将其从 12:59:00 的卷中删除。
例如
t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02;time:12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL;volume:100 25000 26000 0; closingvol: 24000 24000 21000 21000)
**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|15:59:00|AAPL|25000|24000
2019-02-02|12:59:00|AAPL|26000|21000
2019-02-02|15:59:00|AAPL|0|21000
我想成为
**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-02|12:59:00|AAPL|5000|21000
2019-02-02|15:59:00|AAPL|0|21000
我希望我可以避开下面的问题,但是 "or" 的行为似乎不像我希望的那样,因为它从不修改第二个 12:59:00 条目。
update volume:volume-closingvol from t where (time=15:59:00 | time=12:59:00), volume>=closingvol
**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-02|12:59:00|AAPL|26000|21000
2019-02-02|15:59:00|AAPL|0|21000
** 更新 1**
按照建议我也试过了:
更新 volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00, volume>=closingvol
例如如下所示,所有卷都已更新。我本来预计在 2019.02.01 只更新 AAPL 的 15:59:00 和 BAC 的 12:59:00,而在 2019.02.02 只更新 BAC 的 15:59:00 和 12:59:00 对于 AAPL,但这修改了 12:59:00 和 15:59:00.
的所有实例t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02 2019.02.02 2019.02.02 2019.02.01 2019.02.01;time:12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL`BAC`BAC`BAC`BAC;volume:100 25000 26000 0 20000 12000 13000 0; closingvol: 24000 24000 21000 21000 11000 11000 12000 12000)
t:`date`time xasc t
update volume:volume-closingvol from t where (time=15:59:00)|(time=12:59:00), volume>=closingvol
**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|12:59:00|BAC|1000|12000
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-01|15:59:00|BAC|0|12000
2019-02-02|12:59:00|AAPL|5000|21000
2019-02-02|12:59:00|BAC|9000|11000
2019-02-02|15:59:00|AAPL|0|21000
2019-02-02|15:59:00|BAC|1000|11000
目前,当 q 从右到左评估 where 子句中的每个约束时,会发生以下情况:
q)time:12:59:00 15:59:00 12:59:00 15:59:00
q)15:59:00 | time=12:59:00
15:59:00 15:59:00 15:59:00 15:59:00
|在这种情况下表现得像最大值: http://code.kx.com/q/ref/arith-integer/#or-maximum
只需更改括号的位置:
q)update volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00, volume>=closingvol
date time sym volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100 24000
2019.02.01 15:59:00 AAPL 1000 24000
2019.02.02 12:59:00 AAPL 5000 21000
2019.02.02 15:59:00 AAPL 0 21000
为次要示例编辑 -
您可以利用 fby (http://code.kx.com/q/ref/qsql/#fby),这将允许您添加额外的约束,为每个 [=25] 更新最大记录(时间 12:59 或 15:59) =]:
q)update volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00,volume>=closingvol,time=(max;time)fby ([]date;sym)
date time sym volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100 24000
2019.02.01 12:59:00 BAC 1000 12000
2019.02.01 15:59:00 AAPL 1000 24000
2019.02.01 15:59:00 BAC 0 12000
2019.02.02 12:59:00 AAPL 5000 21000
2019.02.02 12:59:00 BAC 20000 11000
2019.02.02 15:59:00 AAPL 0 21000
2019.02.02 15:59:00 BAC 1000 11000
vector conditional ?
在这里可能会有用:
update volume:?[time in 12:59:00 15:59:00;volume-closingvol;volume] from t where vol>=closingvol
第一个参数需要一个布尔列表 - 由 time in 12:59:00 15:59:00
检查创建,并应用第一个条件(删除 closingvol),其中此列表 returns 为真,否则应用第二个条件(离开原样的音量)。
您的示例表明对于同一日期,sym 对,两次交易量都可能大于收盘量 - (12:59:00 15:59:00)。这就是条件 'vol>=closingvol' 给出错误答案的原因(您在您的示例中使用了该答案,也用于您的 post 的其他答案)。
以下解决方案将基于以下假设工作:
- 所有日期、符号组合都有两个时间 - (12:59:00 15:59:00)。
- 数据按时间排序。
即使上述假设在实际场景中不成立,也很容易更改以下查询以根据该假设工作。
q) t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02 2019.02.02 2019.02.02 2019.02.01 2019.02.01;time:12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL`BAC`BAC`BAC`BAC;volume:100 25000 26000 0 20000 12000 13000 0; closingvol: 24000 24000 21000 21000 11000 11000 12000 12000)
q) update volume:{?[0=x 1;(x[0]-y[0]),x 1;x[0],x[1]-y[1]]}[volume;closingvol] by date,sym from t where time in (12:59:00 15:59:00)
或同一查询的其他版本:
q) update volume: volume-closingvol*(0 1;1 0)0=volume 1 by date,sym from t where time in (12:59:00 15:59:00)
date time sym volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100 24000
2019.02.01 15:59:00 AAPL 1000 24000
2019.02.02 12:59:00 AAPL 5000 21000
2019.02.02 15:59:00 AAPL 0 21000
2019.02.02 12:59:00 BAC 20000 11000
2019.02.02 15:59:00 BAC 1000 11000
2019.02.01 12:59:00 BAC 1000 12000
2019.02.01 15:59:00 BAC 0 12000
您还可以通过将 x 和 y 替换为 volume 和 closingvol 来避免查询中的 lambda 函数。我用这种方法让它变小了一点。