4

カスタム Estimator の transformSchema メソッドの場合、入力データ フレームのスキーマをケース クラスで定義されたスキーマと比較できる必要があります。通常、これは、以下に概説するように、ケース クラスから Spark StructType / Schema を生成するように実行できます。ただし、間違った nullability が使用されています。

によって推論される df の実際のスキーマは次のspark.read.csv().as[MyClass]ようになります。

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

そしてケースクラス:

case class MySchema(CUSTOMER_ID: Int)

比較するには、次を使用します。

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

残念ながらfalse、ケース クラスから手動で推論された新しいスキーマが nullable に設定されているため、これは常に生成されますtrue(ja java.Integer が実際には null である可能性があるため)。

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

nullable = falseスキーマの作成時にどのように指定できますか?

4

1 に答える 1

10

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

さらに、次のように定義されたクラスのスキーマ:

case class MySchema(CUSTOMER_ID: Int)

nullable はありませんCUSTOMER_IDscala.Intと同じではありませんjava.lang.Integer:

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))

nullableフィールドが必要な場合は、次のように述べられていますOption[Int]

case class MySchema(CUSTOMER_ID: Option[Int])

上記のようにnull許容しない場合は使用Intします。

ここで発生するもう 1 つの問題は、csvすべてのフィールドが定義により null 可能であり、この状態が encoded によって「継承」されることDatasetです。したがって、実際には:

spark.read.csv(...)

常に次のようになります。

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

これが、スキーマの不一致が発生する理由です。残念ながら、または などnullableの null 可能性制約を適用しないソースのフィールドをオーバーライドすることはできません。csvjson

null 可能なスキーマを持たないことが難しい要件である場合は、次を試すことができます。

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

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

于 2016-11-27T15:20:09.300 に答える