Maison > base de données > tutoriel mysql > Comment sélectionner efficacement la ligne supérieure de chaque groupe dans Spark ?

Comment sélectionner efficacement la ligne supérieure de chaque groupe dans Spark ?

Susan Sarandon
Libérer: 2025-01-23 12:57:10
original
1020 Les gens l'ont consulté

How to Efficiently Select the Top Row for Each Group in Spark?

Sélectionnez efficacement la première ligne de chaque groupe

Cet article vise à extraire la ligne de données avec la « valeur totale » la plus élevée dans chaque groupe « heure » et « catégorie ». Il existe plusieurs façons de procéder :

Utiliser les fonctions de fenêtre :

Les fonctions de fenêtre offrent un moyen efficace d'effectuer des calculs au sein de chaque groupe. Voici une façon de procéder :

<code>import org.apache.spark.sql.functions.{row_number, max, broadcast}
import org.apache.spark.sql.expressions.Window

val w = Window.partitionBy($"Hour").orderBy($"TotalValue".desc)

val dfTop = df.withColumn("rn", row_number.over(w)).where($"rn" === 1).drop("rn")</code>
Copier après la connexion

Utilisation des agrégations et jointures SQL :

Une autre approche consiste à utiliser l'agrégation SQL et les jointures ultérieures :

<code>val dfMax = df.groupBy($"Hour".as("max_hour")).agg(max($"TotalValue").as("max_value"))

val dfTopByJoin = df.join(broadcast(dfMax),
    ($"Hour" === $"max_hour") && ($"TotalValue" === $"max_value"))
  .drop("max_hour")
  .drop("max_value")</code>
Copier après la connexion

Utiliser le tri par structure :

Une manière intelligente consiste à trier une structure contenant « Valeur totale » et « Catégorie » :

<code>val dfTop = df.select($"Hour", struct($"TotalValue", $"Category").alias("vs"))
  .groupBy($"Hour")
  .agg(max("vs").alias("vs"))
  .select($"Hour", $"vs.Category", $"vs.TotalValue")</code>
Copier après la connexion

Utilisation de l'API DataSet (Spark 1.6) :

L'API DataSet fournit un moyen concis d'obtenir le même résultat :

<code>case class Record(Hour: Integer, Category: String, TotalValue: Double)

df.as[Record]
  .groupBy($"Hour")
  .reduce((x, y) => if (x.TotalValue > y.TotalValue) x else y)</code>
Copier après la connexion

Comment éviter les erreurs :

Les méthodes suivantes peuvent produire des résultats peu fiables et doivent être évitées :

  • df.orderBy(...).groupBy(...).agg(first(...), ...)
  • df.orderBy(...).dropDuplicates(...)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal