时间戳 StructField 中的空值
Posted
技术标签:
【中文标题】时间戳 StructField 中的空值【英文标题】:Null values in timestamp StructField 【发布时间】:2018-06-21 14:47:16 【问题描述】:如何处理时间戳列中的空值?
我在 List 中保存了源数据(sql 的结果)
List([222,1,222,222,2012-01-28 23:37:06.0,()],
[220,1,220,220,2012-04-24 23:37:08.0,()],
[220,1,220,220,2008-03-18 15:06:09.0,()],
...
最后一列是空值和时间戳。
但是当我尝试将其加载为 RDD 时
//Create RDD
val rdd = spark.sparkContext.makeRDD(res.toList)
// Create schema fields
val fields = List (StructField("value", StringType, nullable = true)
,StructField("hit_count", IntegerType, nullable = true)
,StructField("range_start", StringType, nullable = true)
,StructField("range_end", StringType, nullable = true)
,StructField("valid_from", TimestampType, nullable = true)
,StructField("valid_to", TimestampType, nullable = true))
// Create DataFrame
val dataFrame = spark.createDataFrame(rdd, StructType(fields))
我遇到了异常
原因:java.lang.RuntimeException:scala.runtime.BoxedUnit 不是 时间戳模式的有效外部类型
因此,Null 值被包装为 BoxedUnit,其类型与 TimestampType 不同。
我该如何处理?是否可以在一列中混合数据类型,还是必须将所有空值映射到“空时间戳”?
【问题讨论】:
您能否描述一下 input 列表值 ([222,1,222,222,2012-01-28 23:37:06.0,()]
) 的结构?每一行对应的每个条目的数据类型是什么?里面的细胞是什么类型的?
您是如何生成该列表的?这就是问题所在。您在该列中有 Unit
值,而不是 null
s。 (列中是否有任何时间戳或全部为Unit
?
【参考方案1】:
您的res
数据中有scala.runtime.BoxedUnit
数据类型([222,1,222,222,2012-01-28 23:37:06.0,()])
当您将时间戳模式应用于 BoxedUnit
时,这就是您面临的异常的主要原因原因:java.lang.RuntimeException:scala.runtime.BoxedUnit 不是时间戳模式的有效外部类型
所以你可以做的是在rdd
中类型检查,如果找到BoxedUnit
,那么你可以用有效的timestamp
替换。为了测试,我使用了valid_from
时间戳
//Create RDD
val rdd = spark.sparkContext.makeRDD(res)
.map(row => Row(row(0), row(1), row(2), row(3), row(4), if(row(5).isInstanceOf[BoxedUnit]) row(4) else row(5)))
我所做的只是添加了一个 类型检查 已完成的地图
希望回答对你有帮助
【讨论】:
这行得通!当我做val rdd = spark.sparkContext.makeRDD(res.toList).map(row => Row(row(0), row(1), row(2), row(3), row(4), if(row(5).isInstanceOf[BoxedUnit]) null else row(5)))
时,我得到了我想要的。非常感谢。以上是关于时间戳 StructField 中的空值的主要内容,如果未能解决你的问题,请参考以下文章
将 unix_timestamp 转换为 spark 中的普通时间戳(以秒为单位)
Sqoop 增量追加模式不为 --check-column 导入空行,该列是时间戳,具有空值