J'ai besoin d'une fonction de fenêtre qui partitionne par certaines clés (= noms de colonnes), trie par un autre nom de colonne et renvoie les lignes avec les x premiers rangs.
Cela fonctionne bien pour l'ordre croissant:
def getTopX(df: DataFrame, top_x: String, top_key: String, top_value:String): DataFrame ={
val top_keys: List[String] = top_key.split(", ").map(_.trim).toList
val w = Window.partitionBy(top_keys(1),top_keys.drop(1):_*)
.orderBy(top_value)
val rankCondition = "rn < "+top_x.toString
val dfTop = df.withColumn("rn",row_number().over(w))
.where(rankCondition).drop("rn")
return dfTop
}
Mais lorsque j'essaye de le changer en orderBy(desc(top_value))
ou orderBy(top_value.desc)
à la ligne 4, j'obtiens une erreur de syntaxe. Quelle est la syntaxe correcte ici?
Il existe deux versions de orderBy
, une qui fonctionne avec des chaînes et une qui fonctionne avec des objets Column
( API ). Votre code utilise la première version, ce qui ne permet pas de modifier l'ordre de tri. Vous devez basculer vers la version de colonne, puis appeler la méthode desc
, par exemple, myCol.desc
.
Maintenant, nous entrons dans le territoire de conception d'API. L'avantage de passer des paramètres Column
est que vous avez beaucoup plus de flexibilité, par exemple, vous pouvez utiliser des expressions, etc. Si vous voulez maintenir une API qui accepte une chaîne par opposition à un Column
, vous devez convertir la chaîne en colonne. Il existe plusieurs façons de procéder et la plus simple consiste à utiliser org.Apache.spark.sql.functions.col(myColName)
.
En mettant tout cela ensemble, nous obtenons
.orderBy(org.Apache.spark.sql.functions.col(top_value).desc)
Supposons, par exemple, que si nous devons trier par une colonne appelée Date
dans l'ordre décroissant de la fonction Window, utilisez le $
symbole avant le nom de la colonne qui nous permettra d'utiliser la syntaxe asc
ou desc
.
Window.orderBy($"Date".desc)
Après avoir spécifié le nom de la colonne entre guillemets, indiquez .desc
qui sera trié par ordre décroissant.
Colonne col = nouvelle colonne ("ts");
col = col.desc ();
WindowSpec w = Window.partitionBy ("col1", "col2"). OrderBy (col);