#date #pyspark #apache-spark-sql #date-format
Вопрос:
У меня есть колонка с датами, где есть несколько записей mm-dd-yy, dd-mm-yy, yy-mm-dd
.
df = sc.parallelize([['12-21-2021'],
['04-23-2021'],
['22-03-24'],
['12/03/20']]).toDF(["Date"])
df.show()
----------
| Date|
----------
|12-21-2021|
|04-23-2021|
| 22-03-24|
| 12/03/20|
----------
Теперь я хочу преобразовать строку в формат даты. Но, как вы можете видеть, результаты для последних двух записей, хотя и получили правильный формат, но столбец результатов принимает неправильный формат. Как мне сделать так, чтобы он принял правильный формат?
from pyspark.sql import functions as F
from pyspark.sql.functions import col, unix_timestamp, to_date
from pyspark.sql.functions import date_format
spark.sql("set spark.sql.legacy.timeParserPolicy=LEGACY")
sdf = df.withColumn("yyyy/MM/dd", F.to_date(F.unix_timestamp(df.Date,'yyyy/MM/dd').cast('timestamp')))
.withColumn("yyyy-MM-dd", F.to_date(F.unix_timestamp(df.Date,'yyyy-MM-dd').cast('timestamp')))
.withColumn("MM/dd/yyyy", F.to_date(F.unix_timestamp(df.Date,'MM/dd/yyyy').cast('timestamp')))
.withColumn("MM-dd-yyyy", F.to_date(F.unix_timestamp(df.Date,'MM-dd-yyyy').cast('timestamp')))
.withColumn("dd/MM/yy", F.to_date(F.unix_timestamp(df.Date,'dd/MM/yy').cast('timestamp')))
.withColumn("dd-MM-yy", F.to_date(F.unix_timestamp(df.Date,'dd-MM-yy').cast('timestamp')))
.withColumn("result", F.coalesce("yyyy/MM/dd", "yyyy-MM-dd", "MM/dd/yyyy", "MM-dd-yyyy",'dd/MM/yy','dd-MM-yy'))
display(sdf)
Date yyyy/MM/dd yyyy-MM-dd MM/dd/yyyy MM-dd-yyyy dd/MM/yy dd-MM-yy result
12-21-2021 null null null 2021-12-21 null null 2021-12-21
04-23-2021 null null null 2021-04-23 null null 2021-04-23
22-03-24 null 0022-03-24 null null null 2024-03-22 0022-03-24
12/03/20 0012-03-20 null 0020-12-03 null 2020-03-12 null 0012-03-20
Комментарии:
1. Изменить
.withColumn("result", F.coalesce("yyyy/MM/dd", "yyyy-MM-dd", "MM/dd/yyyy", "MM-dd-yyyy",'dd/MM/yy','dd-MM-yy'))
на.withColumn("result", F.coalesce('dd/MM/yy','dd-MM-yy',"yyyy/MM/dd", "yyyy-MM-dd", "MM/dd/yyyy", "MM-dd-yyyy"))
2. @User12345 Я попробовал с помощью coalsece, но это не сработало
Ответ №1:
Я протестировал решение, которое работает для меня, надеюсь, оно сработает и для вас.
Некоторые моменты : замена » / » на » — » позволит иметь только 2 разных варианта; но все равно будут неоднозначные значения, поэтому вам нужно будет выбрать заказ для вашего объединения (я не вижу способа определить, является ли дата в формате dd/ММ или MM/dd с некоторыми цифрами). Интересно, не возникнут ли ваши проблемы из-за того, что вы используете cast()
Я позволяю промежуточным форматам видеть конкретный результат, но в моем случае объединение работает.
from pyspark.sql import functions as F, types as T
def TEST_convert_dates(ds_with_dates):
spark.sql("set spark.sql.legacy.timeParserPolicy=LEGACY")
df = ds_with_dates
.withColumn('Date', F.regexp_replace('Date', '/', '-'))
.withColumn('Date_format1', F.to_date(F.col('Date'), 'MM-dd-yy').cast(T.DateType()))
.withColumn('Date_format2', F.to_date(F.col('Date'), 'dd-MM-yy').cast(T.DateType()))
.withColumn('Date_formated', F.coalesce(
F.to_date(F.col('Date'), 'MM-dd-yy').cast(T.DateType()),
F.to_date(F.col('Date'), 'dd-MM-yy').cast(T.DateType())
))
return df
Вот результат:
Date format 1 format 2 Result
12-21-2021 2021-12-21 null 2021-12-21
04-23-2021 2021-04-23 null 2021-04-23
22-03-24 null 2024-03-22 2024-03-22
12/03/20 2020-12-03 2020-03-12 2020-12-03