3

カスタム見積もりの​​transformSchemaメソッドでは、入力データフレームのスキーマとケースクラスで定義されたスキーマを比較できる必要があります。通常、これは下記のようにGenerate a Spark StructType/Schema from a case classのように実行できます。しかし、間違ったNULL値を許可するかどうかが使用されます。正しいnull許容度を持つケースクラスのSparkスキーマ

spark.read.csv().as[MyClass]によって推測DFの本当のスキーマは次のようになります。私が使用して比較するには

case class MySchema(CUSTOMER_ID: Int) 

root 
|-- CUSTOMER_ID: integer (nullable = false) 

とケースクラス

val rawSchema = ScalaReflection.schemaFor[MySchema].dataType.asInstanceOf[StructType] 
    if (!rawSchema.equals(rawDf.schema)) 

残念ながら、これは常にfalseスキーマを作成するとき(JA java.Integerが実際にnullの可能性があるため)、新しいスキーマとして手動でケースから推測されるクラスは

root 
|-- CUSTOMER_ID: integer (nullable = true) 

trueにNULL可能に設定されてどのように私はnullable = falseを指定することができますか?

答えて

3

おそらく、あなたは同じ空間に実際に属していないものを混ぜています。 MLパイプラインは本質的に動的であり、静的に型指定されたオブジェクトを導入しても実際に変更されるわけではありません。定義されるクラスの

またスキーマ:

case class MySchema(CUSTOMER_ID: Int) 

CUSTOMER_IDをNULL可能でいないであろう。あなたは上記のようにNULL可能でない使用にIntをしたい場合は

case class MySchema(CUSTOMER_ID: Option[Int]) 

と:あなたはnullableフィールドOption[Int]をしたい場合は言って

scala> import org.apache.spark.sql.catalyst.ScalaReflection.schemaFor 
import org.apache.spark.sql.catalyst.ScalaReflection.schemaFor 

scala> case class MySchema(CUSTOMER_ID: Int) 
defined class MySchema 

scala> schemaFor[MySchema].dataType 
res0: org.apache.spark.sql.types.DataType = StructType(StructField(CUSTOMER_ID,IntegerType,false)) 

こと:scala.Intjava.lang.Integerと同じではありません。

csvについては、すべてのフィールドが定義可能であり、この状態はエンコードされたDatasetによって「継承」されています。だから、実際には:

spark.read.csv(...) 

はいつもになります:

root 
|-- CUSTOMER_ID: integer (nullable = true) 

とスキーマの不一致を得る理由です。残念ながら、csvまたはjsonのように、NULL可能性制約を適用しないソースに対してnullableフィールドをオーバーライドすることはできません。

NULL可能でないスキーマを持つことは、あなたが試みることができるハード要件である場合:

spark.createDataFrame(
    spark.read.csv(...).rdd, 
    schemaFor[MySchema].dataType.asInstanceOf[StructType] 
).as[MySchema] 

このアプローチでは、データが実際にnull自由であることがわかっている場合にのみ有効です。null実行時例外が発生します。

関連する問題