【问题标题】:how to get first value and last value from dataframe column in pyspark?如何从pyspark的数据框列中获取第一个值和最后一个值?
【发布时间】:2021-12-03 02:14:07
【问题描述】:

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

+----+-----+--------------------+
|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.]

【问题讨论】:

  • 当你说你想要第一个和最后一个值时,你是如何对数据进行排序的,它是按“count”列排序的吗?

标签: apache-spark pyspark apache-spark-sql pyspark-sql


【解决方案1】:

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

另一个想法是将aggfirstlast 聚合函数一起使用。这不起作用! (因为reducers不一定按dataframe的顺序获取记录)

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

最后,由于仅仅为了获取它的第一个和最后一个元素而对数据框进行排序是一种耻辱,我们可以使用 RDD API 和zipWithIndex 来索引数据框并只保留第一个和最后一个元素。

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 谢谢。你能在上面的答案中建议 outoff 吗?
  • 一般来说,我会避免排序。它的价格昂贵。过滤应该快得多。但是,如果数据集已经按某个列排序(我的意思是按 spark 排序),您可能会做得更好。如果是这样,请告诉我。
  • 我的数据集是按支持列排序的。
  • 在这种情况下,执行 df.headdf.orderBy('support desc).head 可能会很有趣,但我并不完全确定 spark 在这种情况下能够执行的优化。
  • 您能否在捕获第一个和最后一个数据之前对数据进行分组时提供帮助 - stackoverflow.com/questions/64004622/…
【解决方案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']

【讨论】:

    【解决方案3】:

    从 3.0.0 版本开始,spark 也有 DataFrame 函数调用 .tail() 获取最后一个值。

    这将返回 Row 对象列表:

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

    【讨论】:

      猜你喜欢
      • 2021-09-05
      • 1970-01-01
      • 2021-11-08
      • 1970-01-01
      • 2019-03-09
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多