在Pyspark中,如何从DataFrame列中获取第一个值和最后一个值?

5

我有一个数据框,我想从数据框列中获取第一个值和最后一个值。

+----+-----+--------------------+
|test|count|             support|
+----+-----+--------------------+
|   A|    5| 0.23809523809523808|
|   B|    5| 0.23809523809523808|
|   C|    4| 0.19047619047619047|
|   G|    2| 0.09523809523809523|
|   K|    2| 0.09523809523809523|
|   D|    1|0.047619047619047616|
+----+-----+--------------------+

期望输出是从支持列的第一个和最后一个值,即 x=[0.23809523809523808,0.047619047619047616.]


1
当你说你想要第一个值和最后一个值时,你是如何对数据进行排序的?它是按“计数”列排序吗? - Shantanu Sharma
3个回答

7

您可以使用 collect,但性能将非常糟糕,因为驱动程序将收集所有数据,只保留第一个和最后一个项目。更糟糕的是,如果您有一个大型数据框架,它很可能会导致OOM错误,因此根本无法工作。

另一个想法是使用aggfirstlast聚合函数。这样做不起作用!(因为规约器不一定按数据框的顺序获取记录)

Spark提供了一个head函数,使得获取第一个元素非常容易。然而,Spark没有提供任何last函数。一个简单的方法是反向排序数据框并再次使用head函数。

first=df.head().support
import pyspark.sql.functions as F
last=df.orderBy(F.monotonically_increasing_id().desc()).head().support

最后,由于仅为了获取DataFrame的第一个和最后一个元素而对其进行排序是一种浪费,我们可以使用RDD API并且 zipWithIndex 给DataFrame加上索引,只保留第一个和最后一个元素。

size = df.count()
df.rdd.zipWithIndex()\
  .filter(lambda x : x[1] == 0 or x[1] == size-1)\
  .map(lambda x : x[0].support)\
  .collect()

@oil 感谢您。您能否建议一下,在以上答案中哪一个在性能方面是最好的。 - Sai
一般情况下,我会避免排序。这是很耗费时间的。过滤应该会快得多。但是,如果数据集已经按某列排序(我指的是由Spark排序),你可能能够做得更好。如果是这种情况,请告诉我。 - Oli
我的数据集按支持列排序。 - Sai
在这种情况下,执行 df.headdf.orderBy('support desc).head 可能会很有趣,但我不完全确定 Spark 在这种情况下能够进行的优化。 - Oli
请问在捕获第一个和最后一个日期之前,数据需要分组时,您能否提供帮助?- https://stackoverflow.com/questions/64004622/pyspark-need-help-in-capturing-first-and-last-date-on-dataset-grouped-by-mul - akash sharma

2
你可以尝试对数据框进行索引,如下所示的示例:

您可以尝试对数据框进行索引,如下所示的示例:

df = <your dataframe>
first_record = df.collect()[0]
last_record = df.collect()[-1]

编辑:你还需要传递列名称。

df = <your dataframe>
first_record = df.collect()[0]['column_name']
last_record = df.collect()[-1]['column_name']

df.collect()[-1] 输出 Row(column_name=value),而 df.collect()[-1]['column_name'] 可以仅提取感兴趣的 column_name 的最后一个值。这正是我所寻找的! - Mario

1

自3.0.0版本以来,Spark还具有名为.tail()的DataFrame函数,用于获取最后一个值。

这将返回Row对象列表:

last=df.tail(1)[0].support

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接