我有以下DataFrame,它有不同日期的键,我希望显示最新日期以及每个键ID对的计数。
输入数据如下:
id key date
11 222 1/22/2017
11 222 1/22/2015
11 222 1/22/2016
11 223 9/22/2017
11 223 1/22/2010
11 223 1/22/2008
我尝试过的代码:
val counts = df.groupBy($"id",$"key").count()
我得到以下输出,
id key count
11 222 3
11 223 3
但是,我希望输出如下:
id key count maxDate
11 222 3 1/22/2017
11 223 3 9/22/2017
答案 0 :(得分:1)
一种方法是将日期转换为unixtime,进行聚合,然后再将其转换回来。可以分别使用unix_timestamp
和from_unixtime
执行与unixtime之间的转换。当日期为unixtime时,可以通过查找最大值来选择最新日期。这种方法唯一可能的缺点是必须明确给出日期格式。
val dateFormat = "MM/dd/yyyy"
val df2 = df.withColumn("date", unix_timestamp($"date", dateFormat))
.groupBy($"id",$"key").agg(count("date").as("count"), max("date").as("maxDate"))
.withColumn("maxDate", from_unixtime($"maxDate", dateFormat))
哪个会给你:
+---+---+-----+----------+
| id|key|count| maxDate|
+---+---+-----+----------+
| 11|222| 3|01/22/2017|
| 11|223| 3|09/22/2017|
+---+---+-----+----------+
答案 1 :(得分:-2)
在两个字段上执行agg
df.groupBy($"id", $"key").agg(count($"date"), max($"date"))
输出:
+---+---+-----------+-----------+
| _1| _2|count(date)| max(date)|
+---+---+-----------+-----------+
| 11|222| 3| 1/22/2017|
| 11|223| 3| 9/22/2017|
+---+---+-----------+-----------+
修改:其他答案中提出的as
选项也相当不错。
修改:以下评论为真。您需要转换为正确的日期格式。您可以查看转换为时间戳或使用udf
import java.text.SimpleDateFormat
import org.apache.spark.sql.{SparkSession, functions}
val simpleDateFormatOriginal:SimpleDateFormat = new SimpleDateFormat("MM/dd/yyyy")
val simpleDateFormatDestination:SimpleDateFormat = new SimpleDateFormat("yyyy/MM/dd")
val toyyyymmdd = (s:String) => {
simpleDateFormatDestination.format(simpleDateFormatOriginal.parse(s))
}
val toddmmyyyy = (s:String) => {
simpleDateFormatOriginal.format(simpleDateFormatDestination.parse(s))
}
val toyyyymmddudf = functions.udf(toyyyymmdd)
val toddmmyyyyyudf = functions.udf(toddmmyyyy)
df.withColumn("date", toyyyymmddudf($"date"))
.groupBy($"id", $"key")
.agg(count($"date"), max($"date").as("maxDate"))
.withColumn("maxDate", toddmmyyyyyudf($"maxDate"))