微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 dropduplicates 时保持最后?

如何解决使用 dropduplicates 时保持最后?

我想保留最后一条记录而不是第一条记录。但是 keep="last" 选项似乎不起作用?例如以下内容

from pyspark.sql import Row
df = sc.parallelize([ \
    Row(name='Alice',age=5,height=80),\
    Row(name='Alice',age=10,height=80)]).toDF()
df.dropDuplicates().show()
+---+------+-----+
|age|height| name|
+---+------+-----+
|  5|    80|Alice|
| 10|    80|Alice|
+---+------+-----+

然后我跑:

df.dropDuplicates(['name','height']).show()
+---+------+-----+
|age|height| name|
+---+------+-----+
|  5|    80|Alice|
+---+------+-----+

我想要以下内容

+---+------+-----+
|age|height| name|
+---+------+-----+
| 10|    80|Alice|
+---+------+-----+

keep=last 似乎不是 pyspark 中的一个选项?

解决方法

执行此类任务的常用方法是计算具有合适分区和排序的排名,并获得 rank = 1 的行:

from pyspark.sql import functions as F,Window

df2 = df.withColumn(
    'rank',F.rank().over(Window.partitionBy('name','height').orderBy(F.desc('age')))
).filter('rank = 1').drop('rank')

df2.show()
+-----+---+------+
| name|age|height|
+-----+---+------+
|Alice| 10|    80|
+-----+---+------+

或者另一种方法是使用 last,但它会给出不确定的结果:

import pyspark.sql.functions as F

df2 = df.groupBy('name','height').agg(
    *[F.last(c).alias(c) for c in df.columns if c not in ['name','height']]
)

df2.show()
+-----+------+---+
| name|height|age|
+-----+------+---+
|Alice|    80| 10|
+-----+------+---+
,

GroupBy 是解决这个问题的更惯用的方法

from pyspark.sql import functions as F

df.groupBy(['name','height'])\
    .agg(F.max('age').alias('age'))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。