时间戳 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 值,而不是 nulls。 (列中是否有任何时间戳或全部为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 中的普通时间戳(以秒为单位)

蜂巢中的时间戳?

Pyspark 列:将字符串格式的数据转换为时间戳格式

Sqoop 增量追加模式不为 --check-column 导入空行,该列是时间戳,具有空值

在 Valetina studio 中获取 mysql 中的当前时间戳

spark中的to_timestamp()函数给出空值