Фильтровать только определенный формат даты в Scala - PullRequest
0 голосов
/ 10 марта 2020

У меня есть кадр данных, в котором некоторые поля имеют формат даты D.HH: мм: сс, D.HH: мм: сс.SSSSSSS & ЧЧ: мм: сс.SSSSSSS. Мне нужно будет отфильтровать только дату типа ЧЧ: мм: ss.SSSSSSS и преобразовать эту дату в секунды (целое число).

Я написал ниже scala код, который преобразует дату в секунды. Мне нужна помощь в фильтрации типа даты определенного формата (ЧЧ: мм: ss.SSSSSSS) и пропустить другие форматы даты в кадре данных. Любая помощь будет оценена.

 def hoursToSeconds(a: Any): Int = {
  val sec = a.toString.split('.')
  val fields = sec(0).split(':')
  val creationSeconds = fields(0).toInt*3600 + fields(1).toInt*60 + fields(2).toInt
  return creationSeconds
}

Ответы [ 2 ]

1 голос
/ 10 марта 2020

Задача может быть разбита на две части:

  1. Отфильтруйте необходимые строки с помощью rlike
  2. рассчитайте секунды в udf

Создайте несколько тестовых данных:

val df = Seq(
   ("one", "1.09:39:26"),
   ("two", "1.09:39:26.1234567"),
   ("three", "09:39:26.1234567")
 ).toDF("info", "time")

Определение регулярного выражения и udf:

val pattern = "\\A(\\d{1,2}):(\\d{2}):(\\d{2})\\.\\d{7}\\z".r

val toSeconds = udf{in: String => {
  val pattern(hour, minute, second) = in
  hour.toInt * 60 * 60 + minute.toInt * 60 + second.toInt
}}

Фактический код:

df
  .filter('time rlike pattern.regex)
  .select('info, 'time, toSeconds('time).as("seconds"))
  .show

печатает

+-----+----------------+-------+
| info|            time|seconds|
+-----+----------------+-------+
|three|09:39:26.1234567|  34766|
+-----+----------------+-------+

Если следует сохранить строки, которые не имеют правильного формата, можно слегка изменить udf и удалить фильтр:

val pattern = "\\A(\\d{1,2}):(\\d{2}):(\\d{2})\\.\\d{7}\\z".r

val toSeconds = udf{in: String => {
  in match {
    case pattern(hour, minute, second)=> hour.toInt * 60 * 60 + minute.toInt * 60 + second.toInt
    case _ => 0
  }
}}

df
  .select('info, 'time, toSeconds('time).as("seconds"))
  .show

отпечатков

+-----+------------------+-------+
| info|              time|seconds|
+-----+------------------+-------+
|  one|        1.09:39:26|      0|
|  two|1.09:39:26.1234567|      0|
|three|  09:39:26.1234567|  34766|
+-----+------------------+-------+
0 голосов
/ 10 марта 2020

Вы можете попробовать сопоставить, используя регулярные выражения с экстракторами, например так:

val dateRegex = """(\d{2}):(\d{2}):(\d{2}).(\d{7})""".r

val D_HH_mm_ss = "1.12:12:12"
val D_HH_mm_ss_SSSSSSS = "1.12:12:12.1234567"
val HH_mm_ss_SSSSSSS = "12:12:12.1234567"

val dates = List(HH_mm_ss_SSSSSSS, D_HH_mm_ss_SSSSSSS, D_HH_mm_ss)

dates.foreach {
  _ match {
    case dateRegex(hh, mm, ss, sssssssss) => println(s"Yay! $hh-$mm-$ss")
    case _ => println("Nay :(")
  }
}
...