Я пишу пакетное задание Spark в Scala, и мне нужно отфильтровать фрейм данных ('driverTable', со столбцом 'date'), чтобы я сохранял только даты ниже 2 лет назад (отбрасывая все остальные столбцы).

val dayList: Seq[Date] = driverTable
        .select("date")
        .as[Date]
        .distinct
        .filter(s"date <= ... ")
        .collect()
        .sortBy(_.getTime)
        .toSeq

DriverTable: org.apache.spark.sql.DataFrame = [имя потока: строка, дата: дата]

«дата» находится в формате java.sql.Date.

Как мне заполнить .filter? Итак, если сегодня 25.05.2021, то мне нужно отфильтровать все дни до 25.05.2019. Если 29 февраля, то 28 февраля за 2 года до этого является порогом.

0
Riccardo Lamera 25 Май 2021 в 12:25
1
Используйте новый объект даты и вычтите из него 2 года, объект даты имеет встроенную функцию для этого .. и вы можете использовать вывод для фильтра u'r. Возможно, вам потребуется применить форматирование даты.
 – 
LiranBo
25 Май 2021 в 12:31
Вообще говоря .. проверьте stackoverflow.com/questions / 55446888 /…
 – 
LiranBo
25 Май 2021 в 12:33
Эта коллекция выглядит сомнительно ...
 – 
thebluephantom
25 Май 2021 в 14:47
Как придешь?
 – 
Riccardo Lamera
25 Май 2021 в 15:22
1
Какой здесь формат date? Вы используете java.sql.Date, java.util.Date или что-то еще? Можете ли вы отредактировать текст своего вопроса, чтобы предоставить пример значения столбца «дата»?
 – 
Coursal
25 Май 2021 в 15:25

1 ответ

Лучший ответ

Вместо того, чтобы намеренно преобразовывать столбец date в java.sql.Date и управлять им как объектом Java, безопаснее преобразовать его в собственную дату Spark с помощью to_date (Scala docs здесь), где вы можете дополнительно указать формат даты, который используется в вашем столбце, с помощью простого аргумента String (как мы будем см. позже).

После этого все, что нам нужно получить, это:

  • текущая дата исполнения, и
  • способ вычисления разницы дат в годах на основе date

Что касается текущей даты, Spark предоставляет current_timestamp() (Scala docs здесь), в котором мы можем применить желаемый формат даты, инкапсулируя его в метод date_format (Документы Scala здесь) (точно так же, как мы используем to_date, как мы упоминали ранее).

Теперь, чтобы вычислить разницу в годах между текущей и указанной датой в столбце date, мы можем воспользоваться методами months_between (Scala docs здесь), который возвращает разницу месяцев в формате Long (как положительные, так и отрицательные числа, поэтому нам нужно получить его абсолютное значение). Вы также можете ознакомиться с этим ответом, чтобы лучше понять его использование.

Допустим, у нас есть следующий входной фрейм данных df с форматом даты yyyy-MM-dd в столбце date:

+---+----------+
| id|      date|
+---+----------+
|  1|2021-05-25|
|  2|2020-05-26|
|  3|2020-05-20|
|  4|2019-05-26|
|  5|2019-05-10|
+---+----------+

Все, что нам нужно сделать, это указать формат даты в date, а затем отфильтровать строки df, проверив, меньше ли абсолютная разница в месяцах между текущей датой и каждой заданной датой, чем 24 месяцев:

df.select("date")
          .withColumn("date", to_date(col("date"), "yyyy-MM-dd"))
          .filter(abs(months_between(col("date"), date_format(current_timestamp(), "yyyy-MM-dd"))) <= 24)

Это приведет к отфильтровыванию дат, которым более 2 лет от текущей даты, как показано ниже:

+----------+
|      date|
+----------+
|2021-05-25|
|2020-05-26|
|2020-05-20|
|2019-05-26|
+----------+
1
Coursal 25 Май 2021 в 16:23