Pilih baris pertama setiap kumpulan dengan cekap
Artikel ini bertujuan untuk mengekstrak baris data dengan "jumlah nilai" tertinggi dalam setiap kumpulan "jam" dan "kategori". Terdapat beberapa cara untuk melakukan ini:
Gunakan fungsi tetingkap:
Fungsi tetingkap menyediakan cara yang cekap untuk melakukan pengiraan dalam setiap kumpulan. Berikut ialah satu cara untuk melakukannya:
<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>
Menggunakan agregasi SQL dan gabungan:
Pendekatan lain ialah menggunakan pengagregatan SQL dan gabungan seterusnya:
<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>
Gunakan pengisihan struktur:
Cara bijak ialah mengisih struct yang mengandungi "Jumlah Nilai" dan "Kategori":
<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>
Menggunakan DataSet API (Spark 1.6):
API Set Data menyediakan cara ringkas untuk mencapai hasil yang sama:
<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>
Cara mengelakkan kesilapan:
Kaedah berikut mungkin menghasilkan hasil yang tidak boleh dipercayai dan harus dielakkan:
df.orderBy(...).groupBy(...).agg(first(...), ...)
df.orderBy(...).dropDuplicates(...)
Atas ialah kandungan terperinci Bagaimana untuk Memilih Baris Teratas dengan Cekap untuk Setiap Kumpulan dalam Spark?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!