【问题标题】:Replace column string name with another column value in Spark Scala用 Spark Scala 中的另一个列值替换列字符串名称
【发布时间】:2021-12-30 21:51:34
【问题描述】:

我有以下数据框,其中有一列 sigN 其他列。

sig 包含嵌入其中的N 列数,如下所示。嵌入的列名称可以是数据框中存在的任意数字。

我想用其他列中的相应值更新sig 列。

例如,

+---------------------------------------------------------------------+------------+------------------+-------------------+--------+
|sig                                                                  |order_timing|po_manl_create_ind|mabd_arrival_status|cut_time|
+---------------------------------------------------------------------+------------+------------------+-------------------+--------+
|R1:BR1-order_timing:BR2-po_manl_create_ind:BR3-mabd_arrival_status:R1|14          |0                 |late               |23      |
|R1:BR1-order_timing:BR2-po_manl_create_ind:BR7-cut_time:R1           |14          |0                 |on_time            |10      |

预期输出

+---------------------------------------------------------------------+------------+-----
|sig                        |order_timing|po_manl_create_ind|mabd_arrival_status|cut_time|
+---------------------------------------------------------------------+------------+-----
|R1:BR1-14:BR2-0:BR3-late:R1|14          |0                 |late               |23      |
|R1:BR1-14:BR2-0:BR7-10:R1  |14          |0                 |on_time            |10      |

【问题讨论】:

    标签: scala apache-spark apache-spark-sql


    【解决方案1】:

    一种方法是使用sig 值中可能出现的列列表来链接多个replace 表达式。

    使用这个示例 DF:

    val df = Seq(
       ("R1:BR1-order_timing:BR2-po_manl_create_ind:BR3-mabd_arrival_status:R1", 14, 0, "late", 23),
       ("R1:BR1-order_timing:BR2-po_manl_create_ind:BR7-cut_time:R1", 14, 0, "on_time", 10),
    ).toDF("sig", "order_timing", "po_manl_create_ind", "mabd_arrival_status", "cut_time")
    

    您可以像这样使用 foldLeft 生成替换表达式 replace_expr

    val replace_expr = df.columns
      .filter(_ != "sig")
      .foldLeft("sig")((acc, c) => s"replace($acc, '$c', $c)")
    
    df.withColumn("sig", expr(replace_expr)).show(false)
    
    //+---------------------------+------------+------------------+-------------------+--------+
    //|sig                        |order_timing|po_manl_create_ind|mabd_arrival_status|cut_time|
    //+---------------------------+------------+------------------+-------------------+--------+
    //|R1:BR1-14:BR2-0:BR3-late:R1|14          |0                 |late               |23      |
    //|R1:BR1-14:BR2-0:BR7-10:R1  |14          |0                 |on_time            |10      |
    //+---------------------------+------------+------------------+-------------------+--------+
    

    【讨论】:

    • 太棒了,看起来像魔术!唯一的问题是,如果任何列包含 NULL,则整个 sig 值将变为 NULL。
    • @Shaun 您可以使用nvl 函数来处理替换值为空的情况。只需将表达式修改为:s"replace($acc, '$c', nvl($c, ''))" 这将在 null 的情况下放置空字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 2019-08-08
    相关资源
    最近更新 更多