当前位置: 首页 > 面试题库 >

在Spark中将包含多种字符串日期格式的列转换为DateTime

暨正真
2023-03-14
问题内容

我的SparkDataDrame中有一个日期列,其中包含多种字符串格式。我想将它们投射到DateTime。

我的专栏中的两种格式是:

  • mm/dd/yyyy; 和
  • yyyy-mm-dd

到目前为止,我的解决方案是使用UDF更改第一个日期格式以匹配第二个日期,如下所示:

import re

def parseDate(dateString):
    if re.match('\d{1,2}\/\d{1,2}\/\d{4}', dateString) is not None:
        return datetime.strptime(dateString, '%M/%d/%Y').strftime('%Y-%M-%d')
    else:
        return dateString

# Create Spark UDF based on above function
dateUdf = udf(parseDate)

df = (df.select(to_date(dateUdf(raw_transactions_df['trans_dt']))))

这行得通,但并不是所有的容错功能。我特别关注:

  • 我尚未遇到的日期格式。
  • mm/dd/yyyy和之间进行区分dd/mm/yyyy(我正在使用的正则表达式目前暂时无法执行此操作)。

有一个更好的方法吗?


问题答案:

我个人建议直接使用SQL函数,而不必进行昂贵且效率低的重新格式化:

from pyspark.sql.functions import coalesce, to_date

def to_date_(col, formats=("MM/dd/yyyy", "yyyy-MM-dd")):
    # Spark 2.2 or later syntax, for < 2.2 use unix_timestamp and cast
    return coalesce(*[to_date(col, f) for f in formats])

这将选择第一种格式,该格式可以成功html" target="_blank">解析输入字符串。

用法:

df = spark.createDataFrame([(1, "01/22/2010"), (2, "2018-12-01")], ("id", "dt"))
df.withColumn("pdt", to_date_("dt")).show()



+---+----------+----------+
| id|        dt|       pdt|
+---+----------+----------+
|  1|01/22/2010|2010-01-22|
|  2|2018-12-01|2018-12-01|
+---+----------+----------+

速度比快udf,添加新格式仅是调整formats参数的问题。

但是,它不会帮助您解决格式歧义问题。在一般情况下,如果没有人工干预和与外部数据的交叉引用,可能无法做到这一点。

当然可以在Scala中完成同一件事:

import org.apache.spark.sql.Column
import org.apache.spark.sql.functions.{coalesce, to_date}

def to_date_(col: Column, 
             formats: Seq[String] = Seq("MM/dd/yyyy", "yyyy-MM-dd")) = {
  coalesce(formats.map(f => to_date(col, f)): _*)
}


 类似资料:
  • 我正在尝试用varchar列中的更新日期列 这里,是varchar数据类型,是日期数据类型。有多种类型的日期格式,例如,09302012, 9/30/2012, 2012-09-30和更多不同的类型 如何编写单个查询以在单个查询中使用各种类型的日期格式更新列。 已编辑::: 抱歉搞砸了...我刚刚意识到这些是ssis包中的单独(部分)更新... 我们有不同类型(6)的品牌,每个品牌都会发送不同日期

  • 问题内容: 我想要这种格式 问题答案: 您需要先 解析 日期字符串(使用方法),才能 使用与格式匹配的格式获取对象。 然后使用所需的格式来 格式化 Date对象(Use 方法)以获取字符串。 输出:- 第一种格式是RFC 822 TimeZone与您的日期字符串匹配。有关在日期格式中使用的其他各种选项,请参见。

  • 问题内容: 我正在尝试将字符串转换为日期格式,我尝试了很多方法来实现此目的,但是没有成功。我的字符串是“ 2012年1月17日”。我想将其转换为“ 2011-10-17”。有人可以告诉我这样做的方法吗?如果您通过示例工作过,那将是真正的帮助! 问题答案:

  • 我得到一串零。有人能帮忙吗?

  • 问题内容: 我想将此字符串转换为以下日期格式。 我收到此错误: 问题答案: 嗯,是。您传递给的构造函数的参数表示您希望日期采用的格式。 对于“ 2013年2月26日,星期二”之类的输入有效。它甚至不是 稍微 有效期为“2013年2月26日”。您知道您正在 解析 文本,而不是对其进行格式化吗? 看起来您想要的格式字符串为“ M-dd-yyyy”或可能为“ Md-yyyy”。 如果尝试将一种格式转换为

  • 我有一个输入日期作为字符串,格式为dd/MM/yyyy 现在我想把它转换成日期对象,格式为yyyy-MM-dd 目前我正在做 输入为:“2013年4月2日” 但我的约会对象是… 所需输出为:2013-02-04(不是字符串,而是日期对象)