【问题标题】:Scala Pass window partition dataset to UDFScala 将窗口分区数据集传递给 UDF
【发布时间】:2021-11-14 13:36:01
【问题描述】:

我有一个如下所示的数据框,

Id1 Id2 Id3 TaskId TaskName index
1 11 bc123-234 dfr3ws-45d randomName1 1
1 11 bc123-234 er98d3-lkj randomName2 2
1 11 bc123-234 hu77d9-mnb randomName3 3
1 11 bc123-234 xc33d5-rew deployhere4 4
1 11 xre43-876 dfr3ws-45d randomName1 1
1 11 xre43-876 er98d3-lkj deployhere2 2
1 11 xre43-876 hu77d9-mnb randomName3 3
1 11 xre43-876 xc33d5-rew randomName4 4

我使用 Id3 和 Id2 对数据进行了分区,并添加了 row_number。

我需要执行以下条件:

TaskId "hu77d9-mnb" 应该出现在包含 deploy 的任务名称之前。如上表所示,名称将是随机的,我需要读取分区中的每个名称并查看其中包含部署的名称。

如果部署 taskName 索引大于 taskID 索引,则将该值标记为 1,否则标记为 0。

我需要像这样获得决赛桌:

Id1 Id2 Id3 TaskId TaskName index result
1 11 bc123-234 dfr3ws-45d randomName1 1 1
1 11 bc123-234 er98d3-lkj randomName2 2 1
1 11 bc123-234 hu77d9-mnb randomName3 3 1
1 11 bc123-234 xc33d5-rew deployhere4 4 1
1 11 xre43-876 dfr3ws-45d randomName1 1 0
1 11 xre43-876 er98d3-lkj deployhere2 2 0
1 11 xre43-876 hu77d9-mnb randomName3 3 0
1 11 xre43-876 xc33d5-rew randomName4 4 0

我被困在这个地方,如何将分区数据传递给 UDF(或其他函数,如 UDAF)并执行此任务。任何建议都会有所帮助。感谢您的宝贵时间。

【问题讨论】:

    标签: scala apache-spark user-defined-functions azure-databricks


    【解决方案1】:

    “deploy”行的索引和特定行的索引(“hu77d9-mnb”)可以通过Window“first”函数分配给每一行,然后进行比较:

    val df = Seq(
      (1, 11, "bc123-234", "dfr3ws-45d", "randomName1", 1),
      (1, 11, "bc123-234", "er98d3-lkj", "randomName2", 2),
      (1, 11, "bc123-234", "hu77d9-mnb", "randomName3", 3),
      (1, 11, "bc123-234", "xc33d5-rew", "deployhere4", 4),
      (1, 11, "xre43-876", "dfr3ws-45d", "randomName1", 1),
      (1, 11, "xre43-876", "er98d3-lkj", "deployhere2", 2),
      (1, 11, "xre43-876", "hu77d9-mnb", "randomName3", 3),
      (1, 11, "xre43-876", "xc33d5-rew", "randomName4", 4)
    ).toDF("Id1", "Id2", "Id3", "TaskID", "TaskName", "index")
    
    val specificTaskId = "hu77d9-mnb"
    val idsWindow = Window.partitionBy("Id1", "Id2", "Id3")
    
    df.withColumn("deployIndex",
      first(
        when(instr($"TaskName", "deploy") > 0, $"index").otherwise(null),
        true)
        .over(idsWindow))
    
      .withColumn("specificTaskIdIndex",
        first(
          when($"TaskID" === lit(specificTaskId), $"index").otherwise(null),
          true)
          .over(idsWindow))
    
      .withColumn("result",
        when($"specificTaskIdIndex" > $"deployIndex", 0).otherwise(1)
      )
    

    输出(必须删除“deployIndex”和“specificTaskIdIndex”列):

    +---+---+---------+----------+-----------+-----+-----------+-------------------+------+
    |Id1|Id2|Id3      |TaskID    |TaskName   |index|deployIndex|specificTaskIdIndex|result|
    +---+---+---------+----------+-----------+-----+-----------+-------------------+------+
    |1  |11 |bc123-234|dfr3ws-45d|randomName1|1    |4          |3                  |1     |
    |1  |11 |bc123-234|er98d3-lkj|randomName2|2    |4          |3                  |1     |
    |1  |11 |bc123-234|hu77d9-mnb|randomName3|3    |4          |3                  |1     |
    |1  |11 |bc123-234|xc33d5-rew|deployhere4|4    |4          |3                  |1     |
    |1  |11 |xre43-876|dfr3ws-45d|randomName1|1    |2          |3                  |0     |
    |1  |11 |xre43-876|er98d3-lkj|deployhere2|2    |2          |3                  |0     |
    |1  |11 |xre43-876|hu77d9-mnb|randomName3|3    |2          |3                  |0     |
    |1  |11 |xre43-876|xc33d5-rew|randomName4|4    |2          |3                  |0     |
    +---+---+---------+----------+-----------+-----+-----------+-------------------+------+
    

    【讨论】:

    • 嗨@pasha701,谢谢你的回答,它帮助我解决了我的问题。我将其标记为正确。干杯!
    • 当我将内部的 null 更改为 0 时,我将所有值都设为 0,条件不起作用。知道为什么会这样。
    • 不清楚为什么要更改它。 “first”函数使用 Null 来获取第一个非空值。
    • 当我为 $"specificTaskIdIndex" 或 $"deployIndex" 设置 Null 时,条件大于总是返回 1。 1) 例如,null > 35 给出 1 作为结果。 2) 第二个例子 23 > null 也给出 1。 3) null > null 也给出 1。
    • 猜一猜,最好不要修改“specificTaskIdIndex”和“deployIndex”评估,并在“结果”评估期间考虑空值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 2020-06-16
    • 2021-12-06
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多