【问题标题】:Seq[(Int,Int)] with nulls implicitly converted to DataFrame带有空值的 Seq[(Int,Int)] 隐式转换为 DataFrame
【发布时间】:2018-10-24 01:40:22
【问题描述】:

我有一个简单的测试用例,将Seq[(Int,Int)] 转换为 DataFrame:

test("SparkTest 0280") {
  val conf = new SparkConf().set("spark.sql.codegen.wholeStage", "false").set("spark.sql.cbo.enabled", "true")
  val spark = SparkSession.builder().config(conf).master("local").appName("SparkTest").enableHiveSupport().getOrCreate()

  import spark.implicits._

  Seq[(Int,Int)]((null, 1), (2, null), (null, 3)).toDF("a", "b").createOrReplaceTempView("t")
  spark.sql("select a,b,nvl(a,b) from t").show(truncate = false)
}

编译有问题:

Error:(565, 21) an expression of type Null is ineligible for implicit conversion
    Seq[(Int,Int)]((null, 1), (2, null), (null, 3)).toDF("a", "b").createOrReplaceTempView("t")

这里有什么问题?

【问题讨论】:

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


    【解决方案1】:

    您不能像这样直接使用null,因为创建的列的类型为Any(不允许用于数据框)。这可以通过创建 RDD 来确认:

    val rdd: RDD[(Any, Any)] = spark.sparkContext.parallelize(Seq((null, 1), (2, null), (null, 3)))
    

    这是由于 Int 在 Scala 中不可为空,来自 Scala tour

    有九种预定义的值类型,它们不可为空:DoubleFloatLongIntShortByteCharUnit 和 @ 987654334@.

    可以直接使用null 创建具有其他数据类型(如字符串)的列,否则一个简单的解决方案是使用NoneSome

    Seq((None, Some(1)), (Some(2), None), (None, Some(3))).toDF("a", "b"))
    

    【讨论】:

      【解决方案2】:

      如果你想使用nulls,你应该用java.lang.Integers替换Ints

      Seq[(Integer, Integer)]((null, 1), (2, null), (null, 3)).toDF("a", "b")
      // org.apache.spark.sql.DataFrame = [a: int, b: int]
      

      可以为空。

      【讨论】:

      • 是的,谢谢,scala 值类型在处理空值时有点不灵活
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-25
      • 1970-01-01
      • 2013-01-01
      • 2015-02-13
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      相关资源
      最近更新 更多