web-dev-qa-db-fra.com

Comment nommer les colonnes d'agrégat?

J'utilise Spark dans Scala et mes colonnes agrégées sont anonymes. Existe-t-il un moyen pratique de renommer plusieurs colonnes d'un jeu de données? J'ai pensé à imposer un schéma avec as, mais la colonne clé est une structure (en raison de l'opération groupBy), et je ne peux pas trouver comment définir un case class avec un StructType.

J'ai essayé de définir un schéma comme suit:

val returnSchema = StructType(StructField("Edge", StructType(StructField("src", IntegerType, true),
                                                             StructField("dst", IntegerType), true)), 
                              StructField("count", LongType, true))
Edge_count.as[returnSchema]

mais j'ai eu une erreur de compilation:

Message: <console>:74: error: overloaded method value apply with alternatives:
  (fields: Array[org.Apache.spark.sql.types.StructField])org.Apache.spark.sql.types.StructType <and>
  (fields: Java.util.List[org.Apache.spark.sql.types.StructField])org.Apache.spark.sql.types.StructType <and>
  (fields: Seq[org.Apache.spark.sql.types.StructField])org.Apache.spark.sql.types.StructType
 cannot be applied to (org.Apache.spark.sql.types.StructField, org.Apache.spark.sql.types.StructField, Boolean)
       val returnSchema = StructType(StructField("Edge", StructType(StructField("src", IntegerType, true),
12
Emre

J'ai fini par utiliser aliases avec l'instruction select; par exemple.,

ds.select($"key.src".as[Short], 
          $"key.dst".as[Short], 
          $"sum(count)".alias("count").as[Long])

J'ai d'abord dû utiliser printSchema pour déterminer les noms de colonne dérivés:

> ds.printSchema

root
 |-- key: struct (nullable = false)
 |    |-- src: short (nullable = false)
 |    |-- dst: short (nullable = false)
 |-- sum(count): long (nullable = true)
0
Emre

La meilleure solution consiste à nommer explicitement vos colonnes, par exemple,

df
  .groupBy('a, 'b)
  .agg(
    expr("count(*) as cnt"),
    expr("sum(x) as x"),
    expr("sum(y)").as("y")
  )

Si vous utilisez un jeu de données, vous devez fournir le type de vos colonnes, par exemple, expr("count(*) as cnt").as[Long].

Vous pouvez utiliser le DSL directement, mais je trouve souvent qu'il est plus détaillé que de simples expressions SQL.

Si vous souhaitez renommer en masse, utilisez Map puis foldLeft le bloc de données.

14
Sim