迭代Spark Dataframe的列并更新指定的值

时间:2018-05-06 06:50:05

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

要遍历从Hive表创建的Spark Dataframe的列并更新所有出现的所需列值,我尝试了以下代码。

import org.apache.spark.sql.{DataFrame}
import org.apache.spark.sql.functions._
import org.apache.spark.sql.functions.udf

val a: DataFrame = spark.sql(s"select * from default.table_a")

    val column_names: Array[String] = a.columns

    val required_columns: Array[String] = column_names.filter(name => name.endsWith("_date")) 

    val func = udf((value: String) => { if if (value == "XXXX" || value == "WWWW" || value == "TTTT") "NULL" else value } )

    val b = {for (column: String <- required_columns) { a.withColumn(column , func(a(column))) } a}

执行spark shell中的代码时出现以下错误。

scala> val b = {for (column: String <- required_columns) { a.withColumn(column , func(a(column))) } a}
<console>:35: error: value a is not a member of org.apache.spark.sql.DataFrame
       val b = {for (column: String <- required_column_list) { a.withColumn(column , isNull(a(column))) } a}
                                                                                                          ^ 

此外,我尝试了以下语句,但未获得所需的输出。

val b = for (column: String <- required_columns) { a.withColumn(column , func(a(column))) }

变量b创建为Unit而不是Dataframe。

scala> val b = for (column: String <- required_columns) { a.withColumn(column , func(a(column))) }
    b: Unit = ()

请建议任何更好的方法来迭代Dataframe的列并更新列中值的所有出现或更正我错的地方。任何其他解决方案也不胜感激。提前谢谢。

1 个答案:

答案 0 :(得分:2)

而不是 for loop ,您应该使用foldLeft。而且您不需要udf功能,可以使用when 内置功能

val column_names: Array[String] = a.columns

val required_columns: Array[String] = column_names.filter(name => name.endsWith("_date"))

import org.apache.spark.sql.functions._
val b = required_columns.foldLeft(a){(tempdf, colName) => tempdf.withColumn(colName, when(col(colName) === "XXX" || col(colName) === "WWWW" || col(colName) === "TTTT", "NULL").otherwise(col(colName)))}

我希望答案很有帮助

说明:

required_columns.foldLeft(a){(tempdf, colName) => tempdf.withColumn(colName, when(col(colName) === "XXX" || col(colName) === "WWWW" || col(colName) === "TTTT", "NULL").otherwise(col(colName)))}

required_columns是来自a数据框/数据集的列名称数组,其中_date为结束字符串,colName位于withColumn

tempdf是原始数据框/数据集,即a

when functionwithColumn内应用,将所有XXXWWWWWTTTT值替换为NULL

最后foldLeft将所有转换应用数据框返回给b