Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何使用条件删除重复项_Scala_Apache Spark_Apache Spark Sql - Fatal编程技术网

Scala 如何使用条件删除重复项

Scala 如何使用条件删除重复项,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我有以下数据帧df: 如何删除重复项,同时保持每个重复项对的项目id和国家id的级别的最小值 +-------------+-------------+-------------+ |项目标识|国家标识|级别| +-----------+----------+---------------+ | 312330| 13535670| 82| | 312330| 13535670| 369| | 312330| 135356

我有以下数据帧
df

如何删除重复项,同时保持每个重复项对的
项目id
国家id
级别
的最小值

+-------------+-------------+-------------+
|项目标识|国家标识|级别|
+-----------+----------+---------------+
|     312330|  13535670|             82|
|     312330|  13535670|            369|
|     312330|  13535670|            376|
|     319840|  69731210|            127|
|     319840|  69730600|            526|
|     311480|  69628930|            150|
|     311480|  69628930|            138|
|     311480|  69628930|            405|
+-----------+----------+---------------+
预期产出:

+-------------+-------------+-------------+
|项目标识|国家标识|级别|
+-----------+----------+---------------+
|     312330|  13535670|             82|
|     319840|  69731210|            127|
|     319840|  69730600|            526|
|     311480|  69628930|            138|
+-----------+----------+---------------+

我知道如何使用dropDuplicates无条件地删除重复项,但我不知道如何针对我的特定情况执行此操作。

其中一种方法是使用
orderBy
(默认为升序)、
groupBy
和aggregation
first

import org.apache.spark.sql.functions.first
df.orderBy("level").groupBy("item_id", "country_id").agg(first("level").as("level")).show(false)
您还可以使用
.asc
定义升序,使用
.desc
定义降序,如下所示

df.orderBy($"level".asc).groupBy("item_id", "country_id").agg(first("level").as("level")).show(false)
您也可以使用
窗口
行号
功能进行操作,如下所示

import org.apache.spark.sql.expressions.Window
val windowSpec = Window.partitionBy("item_id", "country_id").orderBy($"level".asc)

import org.apache.spark.sql.functions.row_number
df.withColumn("rank", row_number().over(windowSpec)).filter($"rank" === 1).drop("rank").show()

第一种方法将取
级别的最小值,而不是最大值,对吗?第一种方法将取分组的第一行。如果排序是上升的,那么它是最小值,如果是下降的,那么它是最大值。为什么有人会在没有评论的情况下否决投票。请评论缺点,如果你真的想否决投票,以便我可以改进答案,如果答案不合适,那么我将删除它。我只是不明白为什么人们连评论都没有投反对票。我没有投反对票,但你确定
orderBy
with
first
保证有效吗?根据我的经验,它并不总是像你在分布式设置中所期望的那样。与此同时,我看到这个问题的公认答案与我的答案完全相同,因此我倾向于同意投票人的观点,即这个答案是不正确的。