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] at parallelize at:27
しかし、以下のコードを使用してDataFrame
からRDD
を作成しようとすると
account.toDF("ACCT_ID", "M_CD", "C_CD","IND")
エラーが発生しています
Java.lang.UnsupportedOperationException:Anyタイプのスキーマはサポートされていません
null
の値をSeq
に入れるたびにエラーが発生することを分析しました。
Null値を追加する方法はありますか?
問題は、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|
+-------+----+----+---+
また、次のようにnull整数値を宣言するためのよりわかりやすい方法を検討することもできます。
object Constants {
val NullInteger: Java.lang.Integer = null
}
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)