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 ... –