0

輸入轉換字符串的嵌套數組類型迄今爲止的嵌套數組類型:使用UDF火花

f1 : [["2017-08-08","2017/08/08"],["2017-08-08","2017/08/08"]] 

架構F1:ArrayType(ArrayType(StringType))

我想日期值從字符串中使用的火花UDF轉換爲日期格式。 這裏輸入可能有Array[Any]。我已經寫了udf,它適用於像["2017-08-07","2013/08/02"]這樣的單維值。對於單維我UDF將是:

def toDateFormatUdf(dateFormat:String) = udf((dateValue: mutable.WrappedArray[_]) => dateValue match{ 
     case null => null 
     case datevalue: mutable.WrappedArray[String] => datevalue.map(date => new java.sql.Date(new SimpleDateFormat(dateFormat).parse(String.valueOf(date)).getTime)) 
}) 

我與Seq[Row]類型UDF參數,但無法形成邏輯嘗試。有什麼辦法可以在Scala中爲多維數組實現UDF嗎?

回答

0

如果數據有一致的格式你可以cast,但在這裏它會排除yyyy/MM/dd記錄:

val df = Seq((1L, Seq(Seq("2017-08-08", "2017/08/08"), Seq("2017-08-08","2017/08/08")))).toDF("id", "dates") 

df.select($"dates".cast("array<array<date>>")).show(1, false) 
+----------------------------------------------------------------+ 
|dates               | 
+----------------------------------------------------------------+ 
|[WrappedArray(2017-08-08, null), WrappedArray(2017-08-08, null)]| 
+----------------------------------------------------------------+ 

這裏我只重寫格式:

val f1 = "(^[0-9]{4})-([0-9]{2})-([0-9]{2})$".r 
val f2 = "(^[0-9]{4})/([0-9]{2})/([0-9]{2})$".r 

val reformat = udf((xxs: Seq[Seq[String]]) => xxs match { 
    case null => null 
    case xxs => xxs.map { 
    case null => null 
    case xs => xs.map { x=> { 
     x match { 
     case null => null 
     case f1(_, _, _) => x 
     case f2(year, month, day) => s"${year}-${month}-${day}" 
     case _ => null 
     } 
    }} 
    } 
}) 

和投

df.select(reformat($"dates")).show(1, false) 
+----------------------------------------------------------------------------+ 
|UDF(dates)                 | 
+----------------------------------------------------------------------------+ 
|[WrappedArray(2017-08-08, 2017-08-08), WrappedArray(2017-08-08, 2017-08-08)]| 
+----------------------------------------------------------------------------+ 

避免不必要的初始化SimpleDateFormat

+0

是否可以創建一個通用的UDF,它將支持任何維數組的字符串輸入? –

+0

我無法找到通用UDF的解決方案。那麼爲每個維度編寫不同的UDF是一個好主意嗎?類似於一維數組的我的udf參數將是Seq [String],對於2D數組,它將是Seq [Seq [String]],就像明智的3D,4D ... –