Создайте DataFrame с нулевым значением для нескольких столбцов

Я пытаюсь создать DataFrame с помощью RDD.

Сначала я создаю RDD, используя приведенный ниже код -

val account = sc.parallelize(Seq(
                                 (1, null, 2,"F"), 
                                 (2, 2, 4, "F"),
                                 (3, 3, 6, "N"),
                                 (4,null,8,"F")))

Работает нормально -

учетная запись: org.apache.spark.rdd.RDD[(Int, Any, Int, String)] = ParallelCollectionRDD[0] при распараллеливании в: 27

но когда вы пытаетесь создать DataFrame из RDD, используя приведенный ниже код

account.toDF("ACCT_ID", "M_CD", "C_CD","IND")

Я получаю ошибку ниже

java.lang.UnsupportedOperationException: схема для типа Any не поддерживается

Я проанализировал, что всякий раз, когда я помещал значение null в Seq, только я получал ошибку.

Есть ли способ добавить нулевое значение?


person Avijit    schedule 13.09.2016    source источник
comment
используйте 1_   -  person dk14    schedule 13.09.2016


Ответы (2)


Проблема в том, что Any слишком общий тип, и Spark просто не представляет, как его сериализовать. Вы должны явно указать какой-то конкретный тип, в вашем случае Integer. Поскольку null нельзя присвоить примитивным типам в Scala, вы можете вместо этого использовать java.lang.Integer. Итак, попробуйте следующее:

val account = sc.parallelize(Seq(
                                 (1, null.asInstanceOf[Integer], 2,"F"), 
                                 (2, new Integer(2), 4, "F"),
                                 (3, new Integer(3), 6, "N"),
                                 (4, null.asInstanceOf[Integer],8,"F")))

Вот вывод:

rdd: org.apache.spark.rdd.RDD[(Int, Integer, Int, String)] = ParallelCollectionRDD[0] at parallelize at <console>:24

И соответствующий DataFrame:

scala> val df = rdd.toDF("ACCT_ID", "M_CD", "C_CD","IND")

df: org.apache.spark.sql.DataFrame = [ACCT_ID: int, M_CD: int ... 2 more fields]

scala> df.show
+-------+----+----+---+
|ACCT_ID|M_CD|C_CD|IND|
+-------+----+----+---+
|      1|null|   2|  F|
|      2|   2|   4|  F|
|      3|   3|   6|  N|
|      4|null|   8|  F|
+-------+----+----+---+

Также вы можете рассмотреть более чистый способ объявить нулевое целочисленное значение, например:

object Constants {
  val NullInteger: java.lang.Integer = null
}
person Zyoma    schedule 13.09.2016
comment
Как мне поступить, если я использую case class для создания DataFrame, то есть я создаю DataFrame, используя spark.sparkContext.parallellize(Seq(A(_, _), A(_, _))).toDF(), где у меня есть case class A(_, _)? Я пробовал описанную выше технику, но null.asInstanceOf[T] дает мне NullPointerException, а null: T (как сказано в комментарии к вопросу) дает мне an expression of type Null is ineligible for implicit conversion - person y2k-shubham; 16.02.2018

Альтернативный способ без использования RDD:

import spark.implicits._

val df = spark.createDataFrame(Seq(
  (1, None,    2, "F"),
  (2, Some(2), 4, "F"),
  (3, Some(3), 6, "N"),
  (4, None,    8, "F")
)).toDF("ACCT_ID", "M_CD", "C_CD","IND")

df.show
+-------+----+----+---+
|ACCT_ID|M_CD|C_CD|IND|
+-------+----+----+---+
|      1|null|   2|  F|
|      2|   2|   4|  F|
|      3|   3|   6|  N|
|      4|null|   8|  F|
+-------+----+----+---+

df.printSchema
root
 |-- ACCT_ID: integer (nullable = false)
 |-- M_CD: integer (nullable = true)
 |-- C_CD: integer (nullable = false)
 |-- IND: string (nullable = true)
person Marsellus Wallace    schedule 13.06.2017