【问题标题】:How to use withColumn Spark Dataframe scala with while如何在while中使用withColumn Spark Dataframe scala
【发布时间】:2019-03-20 17:55:02
【问题描述】:

这是我的函数应用规则,col mdp_codcat,mdp_idregl,usedRef 根据数组 bRef 中的数据变化。

    def withMdpCodcat(bRef: Broadcast[Array[RefRglSDC]])(dataFrame: DataFrame):DataFrame ={var matchRule = false
    var i = 0
    while (i < bRef.value.size && !matchRule) {
      if ((bRef.value(i).sensop.isEmpty || bRef.value(i).sensop.equals(col("signe")))
        && (bRef.value(i).cdopcz.isEmpty || Lib.matchCdopcz(strTail(col("cdopcz")).toString(), bRef.value(i).cdopcz))
        && (bRef.value(i).libope.isEmpty || Lib.matchRule(col("lib_ope").toString(), bRef.value(i).libope))
        && (bRef.value(i).qualib.isEmpty || Lib.matchRule(col("qualif_lib_ope").toString(), bRef.value(i).qualib))) {
        matchRule = true
        dataFrame.withColumn("mdp_codcat", lit(bRef.value(i).codcat))
        dataFrame.withColumn("mdp_idregl", lit(bRef.value(i).idregl))
        dataFrame.withColumn("usedRef", lit("SDC"))
      }else{
        dataFrame.withColumn("mdp_codcat", lit("NOT_CATEGORIZED"))
        dataFrame.withColumn("mdp_idregl", lit("-1"))
        dataFrame.withColumn("usedRef", lit(""))
      }
      i += 1
    }

    dataFrame
  }


dataFrame : "cdenjp", "cdguic", "numcpt", "mdp_codcat", "mdp_idregl" , mdp_codcat","mdp_idregl","usedRef"  if match add mdp_idregl, mdp_idregl,mdp_idregl with value bRef

示例 - 我的数据框:

val DF = Seq(("tt", "aa","bb"),("tt1", "aa1","bb2"),("tt1", "aa1","bb2")).toDF("t","a","b)
+---+---+---+---+
|  t|  a|  b|  c|
+---+---+---+---+
| tt| aa| bb| cc|
|tt1|aa1|bb2|cc3|
+---+---+---+---+

文件.文本内容:

 ,aa,bb,cc
 ,aa1,bb2,cc3
tt4,aa4,bb4,cc4
tt1,aa1,,cc6


case class TOTO(a: String, b:String, c: String, d:String)


 val text = sc.textFile("file:///home/X176616/file")
 val bRef= textFromCsv.map(row => row.split(",", -1))
      .map(c => TOTO(c(0), c(1), c(2), c(3))).collect().sortBy(_.a)



def withMdpCodcat(bRef: Broadcast[Array[RefRglSDC]])(dataFrame: DataFrame):DataFrame
 dataframe.withColumn("mdp_codcat_new", "NOT_FOUND")  //first init not found, change if while if match 

    var matchRule = false
    var i = 0

    while (i < bRef.value.size && !matchRule) {
      if ((bRef.value(i).a.isEmpty || bRef.value(i).a.equals(signe))
        && (bRef.value(i).b.isEmpty || Lib.matchCdopcz(col(b), bRef.value(i).b))
        && (bRef.value(i).c.isEmpty || Lib.matchRule(col(c), bRef.value(i).c))
        )) {
        matchRule = true
        dataframe.withColumn("mdp_codcat_new", bRef.value(i).d)
        dataframe.withColumn("mdp_mdp_idregl_new" = bRef.value(i).e
       
      }
      i += 1
    }

如果条件为真,最后 df

bRef.value(i).a.isEmpty || bRef.value(i).a.equals(signe))
            && (bRef.value(i).b.isEmpty || Lib.matchCdopcz(b.substring(1).toInt.toString, bRef.value(i).b))
            && (bRef.value(i).c.isEmpty || Lib.matchRule(c, bRef.value(i).c)

+---+---+---+---+-----------+----------+
|  t|  a|  b|  c|mdp_codcat |mdp_idregl|
+---+---+---+---+-----------|----------+
| tt| aa| bb| cc|cc         | other    |
| ab|aa1|bb2|cc3|cc4        | toto     | from bRef if true in while
| cd|aa1|bb2|cc3|cc4        | titi     |
|  b|a1 |b2 |c3 |NO_FOUND   |NO_FOUND  | (not_found if conditional false)
+---+---+---+---+----------------------+
+---+---+---+---+----------------------+

【问题讨论】:

  • 我需要帮助,提前谢谢你
  • 你的列名总是一样吗?这三个名字?,使用udf更新字段值
  • 你应该写下你想要实现的东西,并提供一个简单的输入输出示例。在 spark 这样的环境中,没有理由使用 while 循环进入数据帧
  • Tks 列名在 dataFrame 中是不同的 ex colomns : "cdenjp", "cdguic", "numcpt", "mdp_codcat", "mdp_idregl" , mdp_codcat","mdp_idregl","usedRef"
  • Tks,列名与 dataFrame 中的 ex colomns 不同:“cdenjp”、“cdguic”、“numcpt”、“mdp_codcat”、“mdp_idregl”,如果仅匹配 3 列,则添加新值 mdp_codcat ","mdp_idregl","usedRef" 否则添加 3 列其他值

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


【解决方案1】:

您不能根据运行时值创建数据框架构。我会尝试做的更简单。首先,我将使用默认值创建三列:

dataFrame.withColumn("mdp_codcat", lit(""))
dataFrame.withColumn("mdp_idregl", lit(""))
dataFrame.withColumn("usedRef", lit(""))

然后您可以使用带有广播值的 udf:

def mdp_codcat(bRef: Broadcast[Array[RefRglSDC]]) = udf { (field: String) =>
{
      // Your while and if stuff
      // return your update data
}}

并将每个 udf 应用于每个字段:

dataframe.withColumn("mdp_codcat_new", mdp_codcat(bRef)("mdp_codcat"))

或许能帮上忙

【讨论】:

  • tks 回答@EmiCareOfCell44,我用例子添加了新的细节
猜你喜欢
  • 2020-10-04
  • 1970-01-01
  • 2018-12-26
  • 1970-01-01
  • 1970-01-01
  • 2021-07-13
  • 2020-06-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多