【问题标题】:Dynamically consolidate columns into one column with a list of values将列动态合并为一列,其中包含值列表
【发布时间】:2020-07-21 07:38:26
【问题描述】:

我有一个表 idx,每次构建它时都可以包含许多标记为 `A `B `C 的分组列。这些列通常大约有 2 或 3 个(所以 `A `B 或 `A`B `C),但理论上可能更多。还有一个时间戳列`t和一个浮点列`rslt。

我希望重铸分组列,以便我有 1 列,其中包含先前分组列中的值列表。对于固定数量的列(比如 2 - `A `B),我会使用:

?[`idx;();0b;`c`t`rslt!((+:;(enlist;(`idx;enlist`A);(`idx;enlist`B)));`t;`rslt)]

但是,由于分组列的数量可能不同,我希望替换

(`idx;enlist`A);(`idx;enlist`B)

{enlist (`idx;enlist x)} each aCols

其中 aCols 是列的列表。 (所以aCols:`A`B

?[`idx;();0b;`c`rslt!((+:;(enlist;{(`idx;enlist x),} each aCols));`rslt)]

这不起作用。

我注意到 parse 函数显示括号未在 Developer GUI 中呈现,因此我的代码给出:

`idx ,`A
`idx ,`B

而不是'静态'函数,它给出:

(`idx ,`A)
(`idx ,`B)

这是问题的根源吗?为什么我建立的列表在控制台打印输出中没有用左括号和右括号划分?

你能告诉我哪里可能出错了吗?

感谢和问候,

西蒙

【问题讨论】:

    标签: kdb


    【解决方案1】:

    如果数据看起来像:

    idx:([]t:5?.z.p;A:5?.Q.A;B:5?.Q.A;C:5?.Q.A;rslt:5?10f)
    

    那么你的泛函可以变成:

    ?[`idx;();0b;`c`t`rslt!((+:;enlist,{(`idx;enlist x)}each aCols);`t;`rslt)]
    

    但更简洁的功能方法可能是

    q)?[`idx;();0b;`c`t`rslt!((,';;)/[`A`B`C];`t;`rslt)]
    c     t                             rslt
    --------------------------------------------
    "NGJ" 2009.01.10D17:16:43.689503360 3.927524
    "JBL" 2011.11.04D08:07:14.231674368 5.170911
    "CYF" 2012.03.03D11:18:21.556469184 5.159796
    "HFU" 2017.06.10D02:01:53.890645696 4.066642
    "AEW" 2008.01.01D00:10:18.538771776 1.780839
    

    【讨论】:

    • 道歉特里 - 我一定会在未来添加示例数据。出于兴趣,这将是一个足够接近的样本表:idx:([]t:5?.z.p;A:5?.Q.A;B:5?.Q.A;C:5?.Q.A;rslt:5 ?10f)
    • 好的。然后我的第二个建议有效:?[`idx;();0b;`c`t`rslt!((+:;enlist,{(`idx;enlist x)}each aCols);`t;`rslt)]
    • 由上述解决方案更新
    【解决方案2】:

    这不是您问题的答案,但您无需在此处进行功能更新即可获得您想要的结果。请注意,我对下表的数据进行了猜测。

    q)show idx:([]t:5?.z.p;rslt:5?10f;A:5?10;B:5?10;C:5?10)
    t                             rslt     A B C
    --------------------------------------------
    2010.12.31D03:08:15.054082816 2.124007 9 0 8
    2009.05.26D07:50:10.992718592 7.77882  5 9 6
    2000.03.01D12:40:41.350664308 4.844727 9 5 9
    2002.02.19D06:32:27.078053856 6.827999 7 2 0
    2002.02.23D03:39:47.650230800 1.53227  6 3 0
    q)f:{(y _x),'flip enlist[`c]!enlist flip x y:(),y}
    q)f[idx;`A`B`C]
    t                             rslt     c
    --------------------------------------------
    2010.12.31D03:08:15.054082816 2.124007 9 0 8
    2009.05.26D07:50:10.992718592 7.77882  5 9 6
    2000.03.01D12:40:41.350664308 4.844727 9 5 9
    2002.02.19D06:32:27.078053856 6.827999 7 2 0
    2002.02.23D03:39:47.650230800 1.53227  6 3 0
    q)f[delete A,B from idx;`C]
    t                             rslt     c
    ----------------------------------------
    2010.12.31D03:08:15.054082816 2.124007 8
    2009.05.26D07:50:10.992718592 7.77882  6
    2000.03.01D12:40:41.350664308 4.844727 9
    2002.02.19D06:32:27.078053856 6.827999 0
    2002.02.23D03:39:47.650230800 1.53227  0
    

    【讨论】:

    • 嗨 @creilly 我希望你不介意我问 - 你为什么使用 enlist flip x y:(),y 而不是 enlist flip x y ?另外,enlist[`c] 是否完全等同于(enlist `c)?我很想确保我理解你的代码。非常感谢。西蒙
    • 与 () 的连接是为了确保第二个参数是一个列表,因为 _ (drop) 运算符要求左参数是一个列表。正确登记[c] is equivalent to (enlist c)。
    猜你喜欢
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 2017-02-05
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多