如何替换timestamp类型列中的所有空值?
我希望这更容易,但我似乎无法正确获取类型。 我假设一个解决方案是将列转换为String,在字符串中填写今天的日期,然后重新转换为时间戳,但是,是否有更优雅的解决方案?
val today = java.time.LocalDate.now()
var todayStamp = java.sql.Timestamp.valueOf(today.atStartOfDay());
df = df.na.fill(Map("expiration" -> todayStamp))
结果
java.lang.IllegalArgumentException: Unsupported value type java.sql.Timestamp
今天使用并没有使用unix_timestamp(string).cast("timestamp")
期望列而不是字符串。我想我可以在" ugly"我上面提到的方法。
稍后编辑: 忘记提及,在时间戳列上使用Int或String和df.na.fill方法也会导致错误:
org.apache.spark.sql.AnalysisException: cannot resolve 'coalesce(expiration, 0)' due to data type mismatch: input to function coalesce should all be the same type, but it's [timestamp, int];
答案 0 :(得分:4)
您还可以使用coalesce:
import org.apache.spark.sql.functions._
df.withColumn("expiration", coalesce(col("expiration"), current_timestamp()))
这是一个可重复的例子:
import org.apache.spark.sql.functions._
val df = Seq(
Tuple1(None: Option[Timestamp]),
Tuple1(Some(Timestamp.valueOf("2010-01-01 00:00:00")))
).toDF("expiration")
df.withColumn("expiration", coalesce(col("expiration"), current_timestamp())).show()
答案 1 :(得分:2)
根据文件:
值必须是以下类型:整数,长整数,浮点数,双精度,字符串,布尔值。 替换值会转换为列数据类型。
使用na.fill - 您需要提供整数,Long或String的日期,如果列的类型为“timestamp”,它可能会自动转换为“timestamp”
https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/DataFrameNaFunctions.html
<强>填强>
public Dataset<Row> fill(java.util.Map<String,Object> valueMap)
返回一个替换空值的新DataFrame。
地图的关键是列名,地图的值是替换值。 值必须是以下类型:Integer,Long,Float,Double,String,Boolean 。 替换值将转换为列数据类型。
例如,以下内容将“A”列中的空值替换为字符串“unknown”,将“B”列中的空值替换为数值1.0。
import com.google.common.collect.ImmutableMap;
df.na.fill(ImmutableMap.of("A", "unknown", "B", 1.0));
答案 2 :(得分:0)
你可以简化:
import org.apache.spark.sql.functions._
df.withColumn("expiration",
when($"expiration".isNull, current_timestamp()).otherwise($"expiration"))
答案 3 :(得分:-1)
我可以在Java中做到这一点,首先将列值转换为String,然后使用df.na()将空字符串替换为默认值,然后将该列转换为时间戳。
输入数据
+-------------------+
| date|
+-------------------+
| null|
|2018-04-03 00:00:00|
+-------------------+
我的转变
df.withColumn(
"stringDate",
col("date").cast(DataTypes.StringType))
.na().fill("2018-04-01 00:00:00")
.withColumn("finalDate", col("stringDate").cast(DataTypes.TimestampType))
.select("finalDate");
最终输出
+-------------------+
| finalDate|
+-------------------+
|2018-04-01 00:00:00|
|2018-04-03 00:00:00|
+-------------------+