【问题标题】:separating a string column, converting sub values into float and assigning column labels分隔字符串列,将子值转换为浮点数并分配列标签
【发布时间】:2022-11-08 18:26:01
【问题描述】:

我有一个表 t 和向量时间。

sym vals           
-------------------
A   "3.6, 2.1, 1.8"
B   "2.1, 1.8, 1.6"
C   "2.2, 1.9, 1.6"
D   "1.9, 1.5, 1.3"
E   "2.6, 2.1, 1.9"

times: `0`1`2

我想分隔每一行中的逗号分隔字符串并将每个值转换为浮点数。然后列标签需要是次。我还想删除列 vals。以下语句执行此操作。

t_out: delete vals from t, 'flip exec times!("FFF";",")0:vals from t

sym 1   2   3  
---------------
A   3.6 2.1 1.8
B   2.1 1.8 1.6
C   2.2 1.9 1.6
D   1.9 1.5 1.3
E   2.6 2.1 1.9

为什么exec times!("FFF";",")0:vals from t 在将值转换为浮点数后转置表格?为什么我们需要'flip 而不仅仅是flip?我感谢您的帮助。是否有替代方法来实现这一目标?

【问题讨论】:

    标签: kdb


    【解决方案1】:

    (这里有点猜测,因为您在询问 q 的设计选择。)

    0: 通常用于读取 CSV 文件,您可以在其中每行存储一行,用逗号分隔。此行并不总是具有相同的类型,例如,这可能是一个 CSV 文件(基于您的示例):

    3.6, 2.1, 1.8, 10
    2.1, 1.8, 1.6, 20
    2.2, 1.9, 1.6, 30
    1.9, 1.5, 1.3, 40
    2.6, 2.1, 1.9, 50
    

    所以我们有四列,前三列是浮点列,第四列是长(int)列。

    当您使用 0: 读取 CSV(或者在您的情况下,只是一个类似于 CSV 的字符串列表)时, q 将转置表格,以便您拥有一个包含四个列表的列表。

    q)vals: ("3.6, 2.1, 1.8, 10"; "2.1, 1.8, 1.6, 20"; "2.2, 1.9, 1.6, 30"; "1.9, 1.5, 1.3, 40"; "2.6, 2.1, 1.9, 50")
    q)vals
    "3.6, 2.1, 1.8, 10"
    "2.1, 1.8, 1.6, 20"
    "2.2, 1.9, 1.6, 30"
    "1.9, 1.5, 1.3, 40"
    "2.6, 2.1, 1.9, 50"
    q)("FFFJ"; ",") 0: vals
    3.6 2.1 2.2 1.9 2.6
    2.1 1.8 1.9 1.5 2.1
    1.8 1.6 1.6 1.3 1.9
    10  20  30  40  50 
    

    此列表中的四个列表中的每一个都将正确键入:

    q)first ("FFFJ"; ",") 0: vals
    3.6 2.1 2.2 1.9 2.6
    q)type first ("FFFJ"; ",") 0: vals
    9h
    q)last ("FFFJ"; ",") 0: vals
    10 20 30 40 50
    q)type last ("FFFJ"; ",") 0: vals
    7h
    

    这使得使用起来更容易,因为您没有混合列表的列表。替代方案是:

    q)flip ("FFFJ"; ",") 0: vals
    3.6 2.1 1.8 10
    2.1 1.8 1.6 20
    2.2 1.9 1.6 30
    1.9 1.5 1.3 40
    2.6 2.1 1.9 50
    q)first flip ("FFFJ"; ",") 0: vals
    3.6
    2.1
    1.8
    10
    q)type first flip ("FFFJ"; ",") 0: vals
    0h
    

    我猜这是因为性能,因为在引擎盖下,表实际上是列字典,所以实际上看起来像这样:

    q)`1`2`3`4 ! ("FFFJ"; ",") 0: vals
    1| 3.6 2.1 2.2 1.9 2.6
    2| 2.1 1.8 1.9 1.5 2.1
    3| 1.8 1.6 1.6 1.3 1.9
    4| 10  20  30  40  50 
    

    但同样,你问的是 q 的设计选择,所以我只是猜测。

    您需要使用'flip 而不仅仅是flip 的原因是因为您希望将两个表(被视为字典列表)的每个元素相互连接,因此您使用的是 each 迭代器。你可以阅读它here(如果你向下滚动一点到“高级部分,就在每个左边的标题上方,它会更好地解释它)。

    为了清楚地表明迭代器 ' 正在更改 , 而不是 flip,我会将您的查询写为:

    ... from t ,' flip exec ...
    

    【讨论】:

      【解决方案2】:

      这更像是一种好奇心,但您可以通过使用 by 分组来有效地强制“翻转”自然发生(即使 by 分组毫无意义)

      q)exec times!raze("FFF";",")0:vals by sym:sym from t
      sym| 0   1   2
      ---| -----------
      A  | 3.6 2.1 1.8
      B  | 2.1 1.8 1.6
      C  | 2.2 1.9 1.6
      D  | 1.9 1.5 1.3
      E  | 2.6 2.1 1.9
      

      这也消除了将每个 (,') 附加到横向加入结果的需要

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-06-03
        • 2020-05-01
        • 2010-10-19
        • 1970-01-01
        • 1970-01-01
        • 2021-03-03
        • 1970-01-01
        相关资源
        最近更新 更多