スキーマが次のようなデータフレームがあります。
event: struct (nullable = true)
| | event_category: string (nullable = true)
| | event_name: string (nullable = true)
| | properties: struct (nullable = true)
| | | ErrorCode: string (nullable = true)
| | | ErrorDescription: string (nullable = true)
次のコードを使用して、struct
列properties
を分解しようとしています。
df_json.withColumn("event_properties", explode($"event.properties"))
ただし、次の例外がスローされます。
cannot resolve 'explode(`event`.`properties`)' due to data type mismatch: input to function explode should be array or map type, not StructType(StructField(IDFA,StringType,true),
列properties
を分解するには?
explode
をarray
またはmap
columnsで使用できるため、properties
struct
を変換する必要がありますarray
に、次にexplode
関数を次のように適用します
import org.Apache.spark.sql.functions._
df_json.withColumn("event_properties", explode(array($"event.properties.*"))).show(false)
あなたはあなたの望ましい要件を持っているはずです
エラーメッセージが示すように、構造体型の列ではなく、配列型またはマップ型のみを分解できます。
あなたはただすることができます
df_json.withColumn("event_properties", $"event.properties")
これにより、構造型の新しい列event_properties
が生成されます
構造体のすべての要素を新しい列に変換する場合は、withColumn
を使用できません。ワイルドカード*
を使用してselect
を実行する必要があります。
df_json.select($"event.properties.*")
以下を使用して、構造体をフラット化できます。エラーメッセージの状態として、Explodeがstructに対して機能しません。
val explodeDF = parquetDF.explode($"event") {
case Row(properties: Seq[Row]) => properties.map{ property =>
val errorCode = property(0).asInstanceOf[String]
val errorDescription = property(1).asInstanceOf[String]
Event(errorCode, errorDescription, email, salary)
}
}.cache()
display(explodeDF)