在 PySpark 中使用 to_date 在荷兰语中转换具有不同格式和月份缩写的日期字符串

Posted

技术标签:

【中文标题】在 PySpark 中使用 to_date 在荷兰语中转换具有不同格式和月份缩写的日期字符串【英文标题】:Convert a date string with different formatting's and month abbreviation in Dutch using to_date in PySpark 【发布时间】:2021-12-07 21:05:04 【问题描述】:

我需要将日期字符串转换为 DateType,但使用 to_date 时遇到了一些挑战。

day 的格式效果很好(1 位或 2 位数字),month 是荷兰语缩写,不起作用(仅当缩写等于英语时才有效),year 是 2 位或 4 位数字(缺少几个世纪!)。

将这些全部转换为 DateType 的最佳方法是什么? 我找不到使用格式将语言环境设置为 NL 的选项。

我创建了一个 UDF,但不知道这是否是解决此问题的最佳方法。 世纪的19 值得商榷。

代码:

@F.udf(T.StringType())
def convert_date(s):
    
    month_dict = "jan":"01", "feb":"02", "mrt":"03", "apr":"04", "mei":"05", "jun":"06", "jul":"07", "aug":"08", "sep":"09", "okt":"10", "nov":"11", "dec":"12" 
    
    day, month, year = s.split("-")
    if len(day) == 1:
        day = '0' + day
    if len(year) < 4:
        year = '19' + year
        
    date = day + "-" + month_dict[month] + "-" + year
        
    return date
  
df = df.withColumn('DateOfBirth_new', F.to_date(convert_date(F.col("DateOfBirth"), "dd-M-yyyy"))

日期帧:

df = spark.createDataFrame([
 ["2-feb-1966"],
 ["05-mei-1974"],
 ["3-mrt-83"],
 ["05-mrt-1983"],
 ["12-jun-75"]
]).toDF("DateOfBirth")

【问题讨论】:

【参考方案1】:

这是一个类似的没有 UDF 的解决方案,使用 when 表达式进行月份转换。

month_conversion =     F.expr("""CASE 
    WHEN (month = 'jan') THEN 01 
    WHEN (month = 'feb') THEN 02 
    WHEN (month = 'mrt') THEN 03 
    WHEN (month = 'apr') THEN 04 
    WHEN (month = 'mei') THEN 05 
    WHEN (month = 'jun') THEN 06 
    WHEN (month = 'jul') THEN 07 
    WHEN (month = 'aug') THEN 08 
    WHEN (month = 'sep') THEN 09 
    WHEN (month = 'okt') THEN 10 
    WHEN (month = 'nov') THEN 11 
    WHEN (month = 'dec') THEN 12 
    ELSE NULL END
    """).alias("m")

day_conversion = F.when(F.length("day") == 1, F.concat(F.lit("0"), F.col("day"))).otherwise(F.col("day"))
year_conversion = F.when(F.length("year") < 4, F.concat(F.lit("19"), F.col("year"))).otherwise(F.col("year"))

(df.withColumn("split",
    F.split("DateOfBirth", "-")
)
 .withColumn("day",
    F.col("split").getItem(0)
)
 .withColumn("month",
    F.col("split").getItem(1)
)
.withColumn("year",
    F.col("split").getItem(2)
)
 .select(
    F.concat_ws("-",
        day_conversion,
        month_conversion,
        year_conversion
    ).alias("DateOfBirth_new")
)
.show())

【讨论】:

以上是关于在 PySpark 中使用 to_date 在荷兰语中转换具有不同格式和月份缩写的日期字符串的主要内容,如果未能解决你的问题,请参考以下文章

Pyspark 中的解码替代品

pyspark-生成日期序列

为啥 date_format() 在 Pyspark 中返回错误的一周?

在 pyspark 中的 datetime64 和 datetime 之间转换

如何在 spark sql 连接条件中将字符串数据类型转换为日期:to_date 不起作用并且转换抛出错误

如何将免费日期范围添加到 pyspark df