如何验证数据框的日期列

Posted

技术标签:

【中文标题】如何验证数据框的日期列【英文标题】:How to validate Date Column of dateframe 【发布时间】:2019-06-04 12:55:08 【问题描述】:

我有数据框,其中有几列包含日期数据。我想对列应用验证,如果出现错误的日期,我想用错误消息列更新该数据框。我试过但不能正常工作。 我的示例数据框数据。

+-------+-----+-----------+-------------+
|AirName|Place|TakeoffDate|arriveoffDate|
+-------+-----+-----------+-------------+
|  Delta|  Aus|   11/16/18|     08/06/19|
|  Delta|  Pak|   11/16/18|     08/06/19|
| Vistra|  New|   11/16/18|     15/06/19|
|  Delta|  Aus|   15/16/18|     08/06/19|
| JetAir|  Aus|   11/16/18|         null|
+-------+-----+-----------+-------------+

我试过下面的代码。

val DATE_TIME_FORMAT = "MM-dd-yy"

  def validateDf(row: Row): Boolean = try 
    //assume row.getString(1) with give Datetime string
    java.time.LocalDateTime.parse(row.getString(2), java.time.format.DateTimeFormatter.ofPattern(DATE_TIME_FORMAT))
    true
   catch 
    case ex: java.time.format.DateTimeParseException => 
      // Handle exception if you want
      false
    
  

val validDf = sample1.filter(validateDf(_))
val inValidDf = sample1.except(validDf)

预期的数据帧

+-------+-----+-----------+-------------+-------------+
|AirName|Place|TakeoffDate|arriveoffDate|error message|
+-------+-----+-----------+-------------+-------------+
|  Delta|  Aus|   11/16/18|     08/06/19|             |
|  Delta|  Pak|   11/16/18|     08/06/19|             |
| Vistra|  New|   11/16/18|     15/06/19|wrong date   |
|  Delta|  Aus|   15/16/18|     08/06/19|wrong date   |
| JetAir|  Aus|   11/16/18|         null|             |
+-------+-----+-----------+-------------+-------------+

【问题讨论】:

尝试使用 SimpleDateFormat(DATE_TIME_FORMAT).parse(row.getString(2)) 你的无效结果是什么? @KrzysztofAtłasik java.time.LocalDate.parse(row.getString(2), java.time.format.DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)) 。这里我的数据以 excel 格式呈现,如果 Date 类型,默认类型为 excel 列,但在这里我试图解析 getString 字符串。你知道如何用 row.getDate 选项写同样的东西吗? 【参考方案1】:

我建议使用用户定义函数 (UDF)。

这是一个例子:

测试数据框

val someDF = Seq(
  ("11/16/18", "Aus"),
  ("15/16/18", "Pak"),
  ("11/16/18", "New")
).toDF("TakeoffDate", "Place")

UDF

import org.apache.spark.sql.functions.udf

def isValidDate = udf((A: String) => 

  val DATE_TIME_FORMAT = "MM/dd/yy"

  try
    java.time.LocalDate.parse(A, java.time.format.DateTimeFormatter.ofPattern(DATE_TIME_FORMAT))
    true
   catch 
    case ex: java.time.format.DateTimeParseException => 
      false         
  
)

请注意我使用的是LocalDate 而不是LocalDateTime

用法:

someDF.withColumn("IsValidDate", isValidDate(someDF("TakeoffDate"))).show()

结果:

+-----------+-----+-----------+
|TakeoffDate|Place|IsValidDate|
+-----------+-----+-----------+
|   11/16/18|  Aus|       true|
|   15/16/18|  Pak|      false|
|   11/16/18|  New|       true|
+-----------+-----+-----------+

希望对你有帮助。

问候。

【讨论】:

感谢您的回复,但我错过了要告诉您的一件事,我正在从 excel 文件中读取数据。您知道是否任何具有日期值的列默认具有日期格式而不是字符串格式。我能够用字符串类型处理它。希望你明白我的意思。 不确定我是否理解正确,但也许你在阅读 excel 文件时定义了一个模式?也许this answer 会帮助你。

以上是关于如何验证数据框的日期列的主要内容,如果未能解决你的问题,请参考以下文章

在数据框的其他列上使用多个日期列和条件注释热图

按列名对数据框的列进行排序为日期

基于日期时间列名称的数据框的条件平均值

在日期时间列上合并 2 个数据框的智能算法

更改 Pandas 数据框的日期类型

如何将所有日期格式转换为日期列的时间戳?