【发布时间】:2015-11-28 04:45:44
【问题描述】:
给定表 1,其中有一列“x”类型为字符串。 我想创建带有列“y”的表 2,该列是“x”中给出的日期字符串的整数表示。
基本是在“y”列中保留null 值。
表 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)
而将“x”列的值转换为“y”列的值的用户定义函数(udf)是:
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 )
我没有找到通过 udfs“产生”null 值的方法(当然,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 )
【问题讨论】:
-
简单的解决方案是使用盒装类型:stackoverflow.com/questions/42791912/…
标签: scala apache-spark apache-spark-sql user-defined-functions nullable