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
969 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!

source:php.cn
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