Ste*_*han 4 python apache-spark apache-spark-sql pyspark
我的Spark DataDrame中有一个包含多种字符串格式的日期列.我想将这些转换为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']))))
Run Code Online (Sandbox Code Playgroud)
这可行,但不是所有容错的.我特别关注:
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])
Run Code Online (Sandbox Code Playgroud)
这将选择第一种格式,它可以成功解析输入字符串.
用法:
df = spark.createDataFrame([(1, "01/22/2010"), (2, "2018-12-01")], ("id", "dt"))
df.withColumn("pdt", to_date_("dt")).show()
Run Code Online (Sandbox Code Playgroud)
+---+----------+----------+
| id| dt| pdt|
+---+----------+----------+
| 1|01/22/2010|2010-01-22|
| 2|2018-12-01|2018-12-01|
+---+----------+----------+
Run Code Online (Sandbox Code Playgroud)
它会更快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)): _*)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1744 次 |
| 最近记录: |