当前位置: 首页 > 知识库问答 >
问题:

Spark groupby,对值排序,然后取第一个和最后一个

姜学海
2023-03-14

我使用的是Apache Spark,它的数据帧如下所示:

scala> df.printSchema
root
 |-- id: string (nullable = true)
 |-- epoch: long (nullable = true)


scala> df.show(10)
+--------------------+-------------+
|                 id |        epoch|
+--------------------+-------------+
|6825a28d-abe5-4b9...|1533926790847|
|6825a28d-abe5-4b9...|1533926790847|
|6825a28d-abe5-4b9...|1533180241049|
|6825a28d-abe5-4b9...|1533926790847|
|6825a28d-abe5-4b9...|1532977853736|
|6825a28d-abe5-4b9...|1532531733106|
|1eb5f3a4-a68c-4af...|1535383198000|
|1eb5f3a4-a68c-4af...|1535129922000|
|1eb5f3a4-a68c-4af...|1534876240000|
|1eb5f3a4-a68c-4af...|1533840537000|
+--------------------+-------------+
only showing top 10 rows

我想按id字段分组,以获得id的所有历元时间戳。然后我想按时间戳升序对历代进行排序,然后取第一个和最后一个历代。

我使用了下面的查询,但是第一个最后一个历元值似乎是按照它们在原始数据帧中出现的顺序获取的。我想把第一个和最后一个从一个有序的升序中取出来。

scala> val df2 = df2.groupBy("id").
                 agg(first("epoch").as("first"), last("epoch").as("last"))

scala> df2.show()
+--------------------+-------------+-------------+                              
|                  id|        first|         last|
+--------------------+-------------+-------------+
|4f433f46-37e8-412...|1535342400000|1531281600000|
|d0cba2f9-cc04-42c...|1535537741000|1530448494000|
|6825a28d-abe5-4b9...|1533926790847|1532531733106|
|e963f265-809c-425...|1534996800000|1534996800000|
|1eb5f3a4-a68c-4af...|1535383198000|1530985221000|
|2e65a033-85ed-4e4...|1535660873000|1530494913413|
|90b94bb0-740c-42c...|1533960000000|1531108800000|
+--------------------+-------------+-------------+

如何从按升序历元排序的历元列表中检索第一个和最后一个历元?

共有2个答案

鲁钱明
2023-03-14

只需使用“最小”和“最大”,即可将结果列转换为字符串。这里有一种方法

   import org.apache.spark.sql.functions._
val df = Seq(("6825a28d-abe5-4b9",1533926790847.0),
("6825a28d-abe5-4b9",1533926790847.0),
("6825a28d-abe5-4b9",1533180241049.0),
("6825a28d-abe5-4b9",1533926790847.0),
("6825a28d-abe5-4b9",1532977853736.0),
("6825a28d-abe5-4b9",1532531733106.0),
("1eb5f3a4-a68c-4af",1535383198000.0),
("1eb5f3a4-a68c-4af",1535129922000.0),
("1eb5f3a4-a68c-4af",1534876240000.0),
("1eb5f3a4-a68c-4af",1533840537000.0)).toDF("id","epoch").withColumn("epoch",($"epoch"/1000.0).cast("timestamp"))

    +-----------------+--------------------+
|               id|               epoch|
+-----------------+--------------------+
|6825a28d-abe5-4b9|2018-08-10 18:46:...|
|6825a28d-abe5-4b9|2018-08-10 18:46:...|
|6825a28d-abe5-4b9|2018-08-02 03:24:...|
|6825a28d-abe5-4b9|2018-08-10 18:46:...|
|6825a28d-abe5-4b9|2018-07-30 19:10:...|
|6825a28d-abe5-4b9|2018-07-25 15:15:...|
|1eb5f3a4-a68c-4af| 2018-08-27 15:19:58|
|1eb5f3a4-a68c-4af| 2018-08-24 16:58:42|
|1eb5f3a4-a68c-4af| 2018-08-21 18:30:40|
|1eb5f3a4-a68c-4af| 2018-08-09 18:48:57|
+-----------------+--------------------+

    val df1 = df.groupBy("id").agg(min($"epoch").cast("string").as("first"), max($"epoch").cast("string"). as("last"))
df1.show

    +-----------------+--------------------+--------------------+
|               id|               first|                last|
+-----------------+--------------------+--------------------+
|6825a28d-abe5-4b9|2018-07-25 15:15:...|2018-08-10 18:46:...|
|1eb5f3a4-a68c-4af| 2018-08-09 18:48:57| 2018-08-27 15:19:58|
+-----------------+--------------------+--------------------+


    df1: org.apache.spark.sql.DataFrame = [id: string, first: string ... 1 more field]
郎成弘
2023-03-14

firstlast函数在窗口上下文之外应用时没有意义。所取的值完全是任意的。

相反你应该

>

具有map-

 类似资料:
  • 例如,从下面的代码 这只是一个示例数据集,我有一个包含6000行的数据框,我想找到每列的第一个和最后一个值,其中我还有作为值。我也不知道我的第一个值或最后一个值的索引。 我试过了 很少有人来自Link1,Link2,但没有任何成功。我还想得到第一个元素,而不是最小值。

  • 问题内容: 我有一个要排序的对象数组,每个对象都有两个参数:强度和名称 我想先按强度排序,然后再按字母顺序排序。我正在使用以下代码对第一个参数进行排序。然后如何排序? 谢谢你的帮助。 问题答案: 这样扩展您的排序功能; 一个和比较对字符串 是 字母比较。

  • 问题内容: 我发布此消息是因为该主题刚刚在另一个问题/答案中提出,并且该行为没有得到很好的记录。 考虑数据框 我想获取由column定义的每个组的第一行和最后一行。 我试过了 但是,这并没有给我我所期望的。 如何获得每个组中的实际第一个和最后一个值? 问题答案: 一种选择是使用该方法: 但是,我还没有找到一种将它们整齐地聚合的方法。当然,总是可以使用构造函数: 注意:我明确使用了该属性,否则您必须

  • 问题内容: 具体来说,我有一个模型,该模型具有这样的字段 我希望能够轻松抓取最新的对象。最简单/最佳的方法是什么? 我会想要以下类似的东西吗? 问题答案: 您还可以通过放入模型的Meta来简化事情,然后您就可以 有关更多信息,请参阅文档。您可能还需要设置Meta选项。

  • 问题内容: 我有按日期索引的熊猫。有许多列,但仅在部分时间序列中填充了许多列。我想找到非值第一个和最后一个值的位置,以便提取日期并查看特定列的时间序列有多长时间。 有人能指出我正确的方向,如何去做这样的事情吗?提前致谢。 问题答案: @ behzad.nouri的解决方案完美工作,返回第一个和最后不使用Series.first_valid_index和Series.last_valid_index

  • 问题内容: 对行列表进行排序(在每行的最后一个字段上排序)的最简单方法是什么?每行可能具有可变数量的字段。 就像是 是我想要的,但是sort(1)不需要负数来从末尾而不是从开始选择字段。 我也希望能够选择字段分隔符。 编辑:为问题添加一些特殊性:我要排序的列表是路径名列表。路径名可以是任意深度,因此字段数是可变的。我想对文件名组件进行排序。 此附加信息可能会更改操作行以提取最后一个字段的方式(可以