Обновление 2019-06-24
Вы можете попробовать каждый из допустимых форматов даты и использовать pyspark.sql.functions.coalesce
, чтобы вернуть первый ненулевой результат.
import pyspark.sql.functions as f
def date_from_string(date_str, fmt):
try:
# For spark version 2.2 and above, to_date takes in a second argument
return f.to_date(date_str, fmt).cast("date")
except TypeError:
# For spark version 2.1 and below, you'll have to do it this way
return f.from_unixtime(f.unix_timestamp(date_str, fmt)).cast("date")
possible_date_formats = ["yyyyMMdd", "yyyyMM"]
df = df.withColumn(
"open_date",
f.coalesce(*[date_from_string("open_date", fmt) for fmt in possible_date_formats])
)
df.show()
#+----------+
#| open_date|
#+----------+
#|1950-01-02|
#|1950-01-01|
#+----------+
Оригинальный ответ
Если вы гарантированно будете иметь только строки длиной 6 или 8 символов, простейшей вещью будетдобавьте "01"
в конец коротких строк, чтобы указать первое число месяца.
Вот пример использования pyspark.sql.functions.length()
и pyspark.sql.functions.concat()
:
import pyspark.sql.functions as f
df = df.withColumn(
'open_date',
f.when(
f.length(f.col('open_date')) == 6,
f.concat(f.col('open_date'), "01")
).otherwise(f.col('open_date'))
)
df.show()
#+---------+
#|open_date|
#+---------+
#| 19500102|
#| 19500101|
#+---------+
Затем используйте методы, описанные в thisсообщение (перефразировано ниже) для преобразования в дату.
Для Spark 2.1 и ниже :
df = df.withColumn('open_date', f.from_unixtime(f.unix_timestamp('open_date', 'yyyyMMdd')))
Для Spark 2.2 +
df = df.withColumn('open_date', f.to_date('open_date', 'yyyyMMdd'))