2017-10-05 19 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パラメータを調整するだけですします。

ただし、フォーマットのあいまいさには役立ちません。一般的なケースでは、手動での介入や外部データとの相互参照なしには実行できない場合があります。

関連する問題