我定义了一个带有三个参数的Python函数“ DateTimeFormat”
- 具有日期格式(字符串)的Spark Dataframe列
- 列值的输入格式,例如yyyy-mm-dd(字符串)
- 输出格式,即必须以yyyymmdd(String)的形式返回输入的格式
我现在已在Pyspark中将此功能注册为UDF。
udf_date_time = udf(DateTimeFormat,StringType())
我正在尝试在数据帧选择中调用此UDF,只要输入格式和输出与下面所示不同,它似乎就可以正常工作
df.select(udf_date_time('entry_date',lit('mmddyyyy'),lit('yyyy-mm-dd')))
但是当输入格式和输出格式相同但出现以下错误时,它将失败
df.select('exit_date',udf_date_time('exit_date',lit('yyyy-mm-dd'),lit('yyyy-mm-dd')))
“ DateTimeFormat”恰好接受3个参数。给出2个
但是我显然要向UDF发送三个参数
我已经在Python 2.7和Spark 2.1上尝试了上面的示例
当输入和输出格式相同时,该功能似乎可以在正常的Python中正常工作
>>>DateTimeFormat('10152019','mmddyyyy','mmddyyyy')
'10152019'
>>>
但是在SPARK中运行时,以下代码给出了错误
import datetime
# Standard date,timestamp formatter
# Takes string date, its format and output format as arguments
# Returns string formatted date
def DateTimeFormat(col,in_frmt,out_frmt):
date_formatter ={'yyyy':'%Y','mm':'%m','dd':'%d','HH':'%H','MM':'%M','SS':'%S'}
for key,value in date_formatter.items():
in_frmt = in_frmt.replace(key,value)
out_frmt = out_frmt.replace(key,value)
return datetime.datetime.strptime(col,in_frmt).strftime(out_frmt)
使用下面的代码调用UDF
from pyspark.sql.functions import udf,lit
from pyspark.sql import SparkSession
from pyspark.sql.types import StringType
# Create SPARK session
spark = SparkSession.builder.appName("DateChanger").enableHiveSupport().getOrCreate()
df = spark.read.format("csv").option("header", "true").load(file_path)
# Registering UDF
udf_date_time = udf(DateTimeFormat,StringType())
df.select('exit_date',udf_date_time('exit_date',lit('yyyy-mm-dd'),lit('yyyy-mm-dd'))).show()
CSV文件输入Input file
预期结果是命令
df.select('exit_date',udf_date_time('exit_date',lit('yyyy-mm-dd'),lit('yyyy-mm-dd'))).show()
不应抛出任何错误,例如 DateTimeFormat恰好接受3个参数,但给定2个参数
答案 0 :(得分:0)
我不确定是否有更好的方法可以这样做,但是您可以尝试以下方法。
在这里,我假设您希望日期设置为特定格式,并在out_frmt='yyyy-mm-dd'
函数中为输出格式(DateTimeFormat
)设置了默认值
我添加了一个名为udf_score
的新函数来帮助进行转换。这可能会让您感兴趣
from pyspark.sql.types import StringType
from pyspark.sql.functions import udf, lit
df = spark.createDataFrame([
["10-15-2019"],
["10-16-2019"],
["10-17-2019"],
], ['exit_date'])
import datetime
def DateTimeFormat(col,in_frmt,out_frmt='yyyy-mm-dd'):
date_formatter ={'yyyy':'%Y','mm':'%m','dd':'%d','HH':'%H','MM':'%M','SS':'%S'}
for key,value in date_formatter.items():
in_frmt = in_frmt.replace(key,value)
out_frmt = out_frmt.replace(key,value)
return datetime.datetime.strptime(col,in_frmt).strftime(out_frmt)
def udf_score(in_frmt):
return udf(lambda l: DateTimeFormat(l, in_frmt))
in_frmt = 'mm-dd-yyyy'
df.select('exit_date',udf_score(in_frmt)('exit_date').alias('new_dates')).show()
+----------+----------+
| exit_date| new_dates|
+----------+----------+
|10-15-2019|2019-10-15|
|10-16-2019|2019-10-16|
|10-17-2019|2019-10-17|
+----------+----------+