web-dev-qa-db-ja.com

Sparkで構造体列を分解中にエラーが発生しました

スキーマが次のようなデータフレームがあります。

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)

次のコードを使用して、structpropertiesを分解しようとしています。

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を分解するには?

7
shiva.n404

explodearrayまたはmapcolumnsで使用できるため、propertiesstructを変換する必要がありますarrayに、次にexplode関数を次のように適用します

import org.Apache.spark.sql.functions._
df_json.withColumn("event_properties", explode(array($"event.properties.*"))).show(false)

あなたはあなたの望ましい要件を持っているはずです

6
Ramesh Maharjan

エラーメッセージが示すように、構造体型の列ではなく、配列型またはマップ型のみを分解できます。

あなたはただすることができます

df_json.withColumn("event_properties", $"event.properties")

これにより、構造型の新しい列event_propertiesが生成されます

構造体のすべての要素を新しい列に変換する場合は、withColumnを使用できません。ワイルドカード*を使用してselectを実行する必要があります。

df_json.select($"event.properties.*")
4
Raphael Roth

以下を使用して、構造体をフラット化できます。エラーメッセージの状態として、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)
0
Anush