2017-10-05 98 views
1

我的Spark DataDrame中包含多個字符串格式的日期列。我想將這些轉換爲DateTime。在Spark中包含多個字符串日期格式到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'])))) 

這工作,但不是所有的容錯寬容。我特別關心的是:

  • 日期格式我還沒有遇到。
  • 區分mm/dd/yyyydd/mm/yyyy(我正在使用的正則表達式此刻並不這樣做)。

有沒有更好的方法來做到這一點?

回答

3

個人而言,我會建議使用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]) 

這將選擇第一個格式,它可以成功地解析輸入字符串。

用法:

df = spark.createDataFrame([(1, "01/22/2010"), (2, "2018-12-01")], ("id", "dt")) 
df.withColumn("pdt", to_date_("dt")).show() 
+---+----------+----------+ 
| id|  dt|  pdt| 
+---+----------+----------+ 
| 1|01/22/2010|2010-01-22| 
| 2|2018-12-01|2018-12-01| 
+---+----------+----------+ 

它將比udf更快,並增加新的格式,只是調整formats參數的問題。

然而,它不會幫助你格式歧義。一般情況下,可能無法進行手動干預並與外部數據交叉引用。