#scala #apache-spark #apache-spark-dataset
#scala #apache-spark #apache-spark-dataset
Вопрос:
У меня есть следующий набор данных :
---- ----- -------- ----- --------
| id|date1|address1|date2|address2|
---- ----- -------- ----- --------
| 1| 2019| Paris| 2018| Madrid|
| 2| 2020|New York| 2002| Geneva|
| 3| 1998| London| 2005| Tokyo|
| 4| 2005| Sydney| 2013| Berlin|
---- ----- ------- ------ --------
Я пытаюсь получить самую последнюю дату и соответствующий адрес каждого id
из двух других столбцов. Желаемый результат :
---- ----- -------- ----- -------- -------- -----------
| id|date1|address1|date2|address2|date_max|address_max|
---- ----- -------- ----- -------- -------- -----------
| 1| 2019| Paris| 2018| Madrid| 2019| Paris|
| 2| 2020|New York| 2002| Geneva| 2020| New York|
| 3| 1998| London| 2005| Tokyo| 2005| Tokyo|
| 4| 2005| Sydney| 2013| Berlin| 2013| Berlin|
---- ----- ------- ------ -------- -------- -----------
Есть идеи, как сделать это очень эффективным способом?
Ответ №1:
Вы можете сделать CASE WHEN
, чтобы выбрать более свежую дату / адрес:
import org.apache.spark.sql.functions._
val date_max = when(col("date1") > col("date2"), col("date1")).otherwise(col("date2")).alias("date_max")
val address_max = when(col("date1") > col("date2"), col("address1")).otherwise(col("address2")).alias("address_max")
df = df.select("*", date_max, address_max)
Если вы хотите более масштабируемый вариант со многими столбцами:
val df2 = df.withColumn(
"all_date",
array(df.columns.filter(_.contains("date")).map(col): _*)
).withColumn(
"all_address",
array(df.columns.filter(_.contains("address")).map(col): _*)
).withColumn(
"date_max",
array_max($"all_date")
).withColumn(
"address_max",
element_at($"all_address",
(array_position($"all_date", array_max($"all_date"))).cast("int")
)
).drop("all_date", "all_address")
df2.show
--- ----- -------- ----- -------- ------- ----------
| id|date1|address1|date2|address2|datemax|addressmax|
--- ----- -------- ----- -------- ------- ----------
| 1| 2019| Paris| 2018| Madrid| 2019| Paris|
| 2| 2020| NewYork| 2002| Geneva| 2020| NewYork|
| 3| 1998| London| 2005| Tokyo| 2005| Tokyo|
| 4| 2005| Sydney| 2013| Berlin| 2013| Berlin|
--- ----- -------- ----- -------- ------- ----------
Комментарии:
1. В моем случае у меня есть около пятнадцати столбцов даты и адреса для сравнения. Как я могу использовать
CASE WHEN
функцию с таким количеством столбцов?2. @Mamaf Я обновил свой ответ для многих столбцов