如何从列出的日期中获取最新日期以及总数?
How to get the latest date from listed dates along with the total count?
我有下面的 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
一种方法是将日期转换为 unixtime,进行聚合,然后再将其转换回来。这种与 unixtime 之间的转换可以分别使用 unix_timestamp
和 from_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|
+---+---+-----+----------+
对两个字段执行 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"))
我有下面的 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
一种方法是将日期转换为 unixtime,进行聚合,然后再将其转换回来。这种与 unixtime 之间的转换可以分别使用 unix_timestamp
和 from_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|
+---+---+-----+----------+
对两个字段执行 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"))