给定表1,其中一列“ x”为String类型。我想用“ y”列创建表2,该列是“ x”中给出的日期字符串的整数表示。
重要的是将null值保留在“ y”列中。
表1(数据框df1):
+----------+
| x|
+----------+
|2015-09-12|
|2015-09-13|
| null|
| null|
+----------+
root
|-- x: string (nullable = true)
表2(资料框df2):
+----------+--------+
| x| y|
+----------+--------+
| null| null|
| null| null|
|2015-09-12|20150912|
|2015-09-13|20150913|
+----------+--------+
root
|-- x: string (nullable = true)
|-- y: integer (nullable = true)
用户定义的函数(udf)将“ x”列的值转换为“ y”列的值是:
val extractDateAsInt = udf[Int, String] (
(d:String) => d.substring(0, 10)
.filterNot( "-".toSet)
.toInt )
并且有效,无法处理空值。
即使,我可以做类似的事情
val extractDateAsIntWithNull = udf[Int, String] (
(d:String) =>
if (d != null) d.substring(0, 10).filterNot( "-".toSet).toInt
else 1 )
我发现没有办法null通过udfs “产生” 值(当然,因为Ints不能null)。
我当前用于创建df2的解决方案(表2)如下:
// holds data of table 1
val df1 = ...
// filter entries from df1, that are not null
val dfNotNulls = df1.filter(df1("x")
.isNotNull)
.withColumn("y", extractDateAsInt(df1("x")))
.withColumnRenamed("x", "right_x")
// create df2 via a left join on df1 and dfNotNull having
val df2 = df1.join( dfNotNulls, df1("x") === dfNotNulls("right_x"), "leftouter" ).drop("right_x")
问题:
当前的解决方案似乎很麻烦(并且可能无法有效地提高性能)。有没有更好的办法?
@ Spark-developers:是否有NullableInt计划/可用的类型,以便可以使用以下udf(请参见代码摘录)?
代码摘录
val extractDateAsNullableInt = udf[NullableInt, String] (
(d:String) =>
if (d != null) d.substring(0, 10).filterNot( "-".toSet).toInt
else null )
守着星空守着你
噜噜哒