UDF Spark не изменяет значение столбца с нуля на 0 - PullRequest
1 голос
/ 15 мая 2019

Попытка заменить ноль на 0 в кадре данных, используя UDF ниже. Там, где я могу ошибаться, код кажется простым, но он работает не так, как ожидалось.

Я пытался создать UDF, который заменяет 0 в любом столбце со значением null.

Спасибо всем заранее.

//imports

object PlayGround {
def missingValType2(n: Int):Int = {
    if(n == null){
      0
    }else{
      n
    }
  }

   def main(args: Array[String]): Unit = {

    Logger.getLogger("org").setLevel(Level.ERROR)
    val spark = SparkSession
      .builder()
      .appName("PlayGround")
      .config("spark.sql.warehouse.dir", "file:///C:/temp")
      .master("local[*]")
      .getOrCreate()

    val missingValUDFType2 = udf[Int, Int](missingValType2)

     val schema = List(
      StructField("name", types.StringType, false),
      StructField("age", types.IntegerType, true)
    )

    val data = Seq(
      Row("miguel", null),
      Row("luisa", 21)
    )
    val df = spark.createDataFrame(
      spark.sparkContext.parallelize(data),
      StructType(schema)
    )
    df.show(false)
    df.withColumn("ageNullReplace",missingValUDFType2($"age")).show()

  }
}

/**
  * +------+----+
  * |name  |age |
  * +------+----+
  * |miguel|null|
  * |luisa |21  |
  * +------+----+
  *
  * Below is the current output.
  * +------+----+--------------+
  * |  name| age|ageNullReplace|
  * +------+----+--------------+
  * |miguel|null|          null|
  * | luisa|  21|            21|
  * +------+----+--------------+*/

Ожидаемый результат:

 * +------+----+--------------+
  * |  name| age|ageNullReplace|
  * +------+----+--------------+
  * |miguel|null|             0|
  * | luisa|  21|            21|
  * +------+----+--------------+

Ответы [ 2 ]

2 голосов
/ 15 мая 2019

Нет необходимости в UDF.Вы можете применить na.fill к списку столбцов конкретного типа в DataFrame, как показано ниже:

import org.apache.spark.sql.functions._
import spark.implicits._

val df = Seq(
  ("miguel", None), ("luisa", Some(21))
).toDF("name", "age")

df.na.fill(0, Seq("age")).show
// +------+---+
// |  name|age|
// +------+---+
// |miguel|  0|
// | luisa| 21|
// +------+---+
1 голос
/ 15 мая 2019

вы можете использовать WithColumn с условием когда, как показано ниже Код не проверен

df.withColumn("ageNullReplace", when(col("age").isNull,lit(0)).otherwise(col(age)))

в приведенном выше коде В противном случае не требуется только FYI

Надеюсь, что помогает

...