Python:如果存在空值,如何将Pyspark列转换为日期类型

Jed*_*Jed 3 python null date apache-spark pyspark

在pyspark中,我有一个数据框,其中包含要作为字符串导入的日期。这些按字符串日期的列中有空值。我正在尝试将这些列转换为日期类型的列,但我不断收到错误消息。这是数据框的一个小示例:

+--------+----------+----------+
|DeviceId|   Created| EventDate|
+--------+----------+----------+
|       1|      null|2017-03-09|
|       1|      null|2017-03-09|
|       1|2017-03-09|2017-03-09|
|       1|2017-03-15|2017-03-15|
|       1|      null|2017-05-06|
|       1|2017-05-06|2017-05-06|
|       1|      null|      null|
+--------+----------+----------+
Run Code Online (Sandbox Code Playgroud)

当没有空值时,我发现下面的代码可用于转换数据类型:

dt_func =  udf (lambda x: datetime.strptime(x, '%Y-%m-%d'), DateType())    
df = df.withColumn('Created', dt_func(col('Created')))
Run Code Online (Sandbox Code Playgroud)

一旦添加空值,它就会崩溃。我试图修改udf以解决空值,如下所示:

import numpy as np
def convertDatetime(x):
    return sf.when(x.isNull(), 'null').otherwise(datetime.strptime(x, '%Y-%m-%d'))
dt_func =  udf(convertDatetime, DateType())
Run Code Online (Sandbox Code Playgroud)

我还尝试使用任意日期字符串填充null,将列转换为日期,然后尝试将null替换为任意填充日期,如下所示:

def dt_conv(df, cols, form = '%Y-%m-%d', temp_plug = '1900-01-01'):
    df = df.na.fill(temp_plug)
    dt_func =  udf (lambda x: datetime.strptime(x, form), DateType())

    for col_ in cols:
        df = df.withColumn(col_, dt_func(col(col_)))
    df = df.replace(datetime.strptime(temp_plug, form), 'null')
    return df
Run Code Online (Sandbox Code Playgroud)

但是,这种方法给我这个错误

ValueError: to_replace should be a float, int, long, string, list, tuple, or dict
Run Code Online (Sandbox Code Playgroud)

有人可以帮我解决这个问题吗?

Pus*_*hkr 5

尝试这个 -

# Some data, I added empty strings and nulls both
data = [(1,'','2017-03-09'),(1,None,'2017-03-09'),(1,'2017-03-09','2017-03-09')]

df = spark.createDataFrame(data).toDF('id','Created','EventDate')
df.show()
Run Code Online (Sandbox Code Playgroud)

+---+----------+----------+
| id|   Created| EventDate|
+---+----------+----------+
|  1|          |2017-03-09|
|  1|      null|2017-03-09|
|  1|2017-03-09|2017-03-09|
+---+----------+----------+
Run Code Online (Sandbox Code Playgroud)

df\
.withColumn('Created-formatted',when((df.Created.isNull() | (df.Created == '')) ,'0')\
.otherwise(unix_timestamp(df.Created,'yyyy-MM-dd')))\
.withColumn('EventDate-formatted',when((df.EventDate.isNull() | (df.EventDate == '')) ,'0')\
.otherwise(unix_timestamp(df.EventDate,'yyyy-MM-dd')))\
.drop('Created','EventDate')\
.show()
Run Code Online (Sandbox Code Playgroud)

+---+-----------------+-------------------+
| id|Created-formatted|EventDate-formatted|
+---+-----------------+-------------------+
|  1|                0|         1489035600|
|  1|                0|         1489035600|
|  1|       1489035600|         1489035600|
+---+-----------------+-------------------+
Run Code Online (Sandbox Code Playgroud)

我使用unix_timestamp了返回BigInt格式的格式,但是您可以根据需要格式化该列。