【问题标题】:Filling missing data in a table在表格中填充缺失的数据
【发布时间】:2020-11-27 17:17:34
【问题描述】:

我遇到了丢失数据的问题。 所以我有一个这样创建的退货表:

returns:update logret:log ret from update ret:{0.0, 1_deltas x} mid by sym from spots;

看起来像这样:

meta returns
c     | t f a
------| -----
date  | d    
time  | p    
sym   | s    
mid   | f    
ret   | f    
logret| f    

我以这种方式旋转它:

rettbl:0!exec (raze `$raze ( string (distinct sym)),\:/:("_",/:string `mid`ret`logret))!(mid, ret, logret) by time:time from returns;

这样可以在很小的时间范围内工作,但是当我扩展它时会失败并显示“类型:不匹配的类型”

我认为问题在于我对returns 表中的所有 sym 没有相同的观察结果,如
select count time by sym from returns
按符号给我一个不同的计数。

所以我的问题是:你将如何填补我桌子上所有缺失的mid returns? 为了使其快速而肮脏,我正在考虑对两个`时间之间的缺失点进行线性插值...
任何提示、链接等......将不胜感激。

编辑:
我无法共享数据,但这应该可以重现问题:

mid1: 1.2 + ({rand 1.0} each til 10) %100
mid2: 0.8 + ({rand 1.0} each til 10) %100
mid3: 104 + ({rand 1.0} each til 10) %100
sym1:{`$"EUR/USD"} each til 10
sym2:{`$"GBP/USD"} each til 10
sym3:{`$"USD/JPY"} each til 10
time1:2020.07.01D00:00:00.000000000 + 1D00:00:00 * til 10
/time2:2020.07.01D00:00:00.000000000 + 1D00:00:00 * til 10
time2:(2020.07.01D00:00:00.000000000 + 1D00:00:00 * til 3) , (2020.07.06D00:00:00.000000000 + 1D00:00:00 * til 3) , (2020.07.10D00:00:00.000000000 + 1D00:00:00 * til 4)
time3:2020.07.01D00:00:00.000000000 + 1D00:00:00 * til 10

spots:([] sym:sym1,sym2,sym3; time:time1,time2,time3; mid:mid1,mid2,mid3)
spots:update date:"d"$time from spots
returns:update logret:log ret from update ret:{0.0, 1_deltas x} mid by sym from spots;
rettbl:0!exec (raze `$raze ( string (distinct sym)),\:/:("_",/:string `mid`ret`logret))!(mid, ret, logret) by time:time from returns;

请注意 time2 的定义。
根据所需的输出,如果您将 time2 定义替换为我注释掉的定义,您将看到。
根据解决方案,我怀疑添加到表中会返回丢失的时间,以便所有 sym 相同的时间列表相同将解决问题,即值 select time by sym from returns 应该相同,并且快速脏解决方法是使用周围中间的线性插值添加缺失的中间。

【问题讨论】:

  • 您能提供一个样品退货表吗?
  • 也是一个预期的输出,以便了解您想要什么
  • 嗨,垫子。我尽力创建一个表来重现该问题。我希望我清楚问题的原因(sym 的时间不一样)以及我试图解决的问题:填充退货表,以便退货表的所有时间都存在所有 sym,缺失的中间值将被线性插值。我相信支点会在这些条件下发挥作用。

标签: missing-data kdb linear-interpolation


【解决方案1】:

P# 在这里非常重要,以便正确生成枢轴。这将在 sym col 缺少时间的地方放置空值。 https://code.kx.com/q/kb/pivoting-tables/

{

    P:exec (raze `$raze ( string (distinct sym)),\:/:("_",/:string `mid`ret`logret)) from returns;
    exec P#(raze `$raze ( string (distinct sym)),\:/:("_",/:string `mid`ret`logret))!(mid, ret, logret) by time:time from returns

    }[]

Output:
time                         | EUR/USD_mid GBP/USD_mid USD/JPY_mid EUR/USD_re..
-----------------------------| ----------------------------------------------..
2020.07.01D00:00:00.000000000| 1.203915    0.8078337   104.0062    0         ..
2020.07.02D00:00:00.000000000| 1.200812    0.8040996   104.0093    -0.0031030..
2020.07.03D00:00:00.000000000| 1.209368    0.8061088   104.0027    0.00855514..
2020.07.04D00:00:00.000000000| 1.202782                104.0006    -0.0065853..
2020.07.05D00:00:00.000000000| 1.202392                104.0026    -0.0003897..
2020.07.06D00:00:00.000000000| 1.201508    0.8049765   104.0023    -0.0008842..
2020.07.07D00:00:00.000000000| 1.201567    0.8040875   104.0009    5.91839e-0..
2020.07.08D00:00:00.000000000| 1.209785    0.8044973   104.001     0.00821768..
2020.07.09D00:00:00.000000000| 1.207043                104.0087    -0.0027416..
2020.07.10D00:00:00.000000000| 1.209442    0.8001392   104.0073    0.00239835..
2020.07.11D00:00:00.000000000|             0.8071488                         ..
2020.07.12D00:00:00.000000000|             0.8019465                         ..

您收到类型错误,因为当所有符号都不存在时间时,代码正在创建字典。

q)0!exec (raze `$raze ( string (distinct sym)),\:/:("_",/:string `mid`ret`logret))!(mid, ret, logret) by time:time from returns
'type
  [0]  0!exec (raze `$raze ( string (distinct sym)),\:/:("_",/:string `mid`ret`logret))!(mid, ret, logret) by time:time from returns
        ^
q)exec (raze `$raze ( string (distinct sym)),\:/:("_",/:string `mid`ret`logret))!(mid, ret, logret) by time:time from returns
time                         |                                               ..
-----------------------------| ----------------------------------------------..
2020.07.01D00:00:00.000000000| `EUR/USD_mid`GBP/USD_mid`USD/JPY_mid`EUR/USD_r..
2020.07.02D00:00:00.000000000| `EUR/USD_mid`GBP/USD_mid`USD/JPY_mid`EUR/USD_r..
2020.07.03D00:00:00.000000000| `EUR/USD_mid`GBP/USD_mid`USD/JPY_mid`EUR/USD_r..
2020.07.04D00:00:00.000000000| `EUR/USD_mid`USD/JPY_mid`EUR/USD_ret`USD/JPY_r..
2020.07.05D00:00:00.000000000| `EUR/USD_mid`USD/JPY_mid`EUR/USD_ret`USD/JPY_r..

编辑:要删除空值,您可以使用fills 来填充非空值。您可能还想先使用.Q.id 来清理表格。由于与over / 混淆,EUR/USD_mid 等列难以处理。

https://code.kx.com/q/ref/dotq/#qid-sanitize

q)fills x
time                         | EURUSD_mid GBPUSD_mid USDJPY_mid EURUSD_ret   ..
-----------------------------| ----------------------------------------------..
2020.07.01D00:00:00.000000000| 1.203928   0.8049318  104.0047   0            ..
2020.07.02D00:00:00.000000000| 1.205171   0.8057852  104.0063   0.001243387  ..
2020.07.03D00:00:00.000000000| 1.20516    0.8008389  104.0097   -1.11147e-005..
2020.07.04D00:00:00.000000000| 1.204067   0.8008389  104.0023   -0.001093155 ..
2020.07.05D00:00:00.000000000| 1.201781   0.8008389  104.0095   -0.002285803 ..

这将删除除第一行中存在的任何空值之外的大多数空值。我没有在 kdb 中编写诸如线性插值之类的东西的经验,而且我认为它不会像填充一样替换空值。例如,示例数据集在 EURUSD_mid 列的末尾有 3 个空值,因此无法对这 3 个条目进行插值。

【讨论】:

  • 谢谢你,马特。得到它的 P# 。但问题是,填补缺失的中频并不能真正解决我的问题。因此,在您调整输出后,EUR/USD_mid 的第 11 位和第 12 位为空,GBP/USD_mid 的第 4 位和第 5 位也为空。我想做的是用线性插值填充所有这些 0Nf。对于前 4 日 GBP/USD_mid 将等于 0.8061088 + (0.804977-0.806109)/3 = 0.805731,7 月 11 日 EUR/USD_mid 将是 1.206442 + (1.209442 - 1.207043)。也许这是一个太笼统的问题,但任何指针都会很有用。无论如何感谢P#
  • 好的,我会检查填充和 .Q.id。再次感谢!
猜你喜欢
  • 2020-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
  • 2020-02-20
相关资源
最近更新 更多