gpt4 book ai didi

apache-spark - Spark : cast decimal without changing nullable property of column

转载 作者:行者123 更新时间:2023-12-04 05:14:36 25 4
gpt4 key购买 nike

将列转换为 DecimalTypeDataFrame似乎改变了可空属性。具体来说,我有一个类型为 DecimalType(12, 4) 的不可为空的列。我把它转换到 DecimalType(38, 9)使用 df.withColumn(columnName, df.col(columnName).cast(dataType)) .这会产生一个具有预期数据类型的字段,但该字段现在可以为空。有没有办法在不更改列的可为空属性的情况下进行转换?

我在 Spark 2.2.1 和 Spark 2.3.0 中都观察到了这种行为。

最佳答案

谢谢你的有趣观点。我深入研究了源代码以了解这种行为,而 IMO 的答案是在 Cast.scala 中表示强制转换表达式。公开可空性的属性是这样计算的:

override def nullable: Boolean = Cast.forceNullable(child.dataType, dataType) || child.nullable

def forceNullable(from: DataType, to: DataType): Boolean = (from, to) match {
case (NullType, _) => true
case (_, _) if from == to => false

case (StringType, BinaryType) => false
case (StringType, _) => true
case (_, StringType) => false

case (FloatType | DoubleType, TimestampType) => true
case (TimestampType, DateType) => false
case (_, DateType) => true
case (DateType, TimestampType) => false
case (DateType, _) => true
case (_, CalendarIntervalType) => true

case (_, _: DecimalType) => true // overflow
case (_: FractionalType, _: IntegralType) => true // NaN, infinity
case _ => false
}

如您所见,从任何类型到 DecimalType 的转换始终返回可空类型。我想知道为什么,这可能是因为这里表达的溢出风险:
/**
* Change the precision / scale in a given decimal to those set in `decimalType` (i f any),
* returning null if it overflows or modifying `value` in-place and returning it if successful.
*
* NOTE: this modifies `value` in-place, so don't call it on external data.
*/
private[this] def changePrecision(value: Decimal, decimalType: DecimalType): Decimal = {
if (value.changePrecision(decimalType.precision, decimalType.scale)) value else null
}
changePrecision方法依次检查是否可以修改精度,如果是,则返回 true,否则返回 false。它解释了为什么上述方法可以返回 null 以及为什么 DecimalType 在独立于源类型强制转换时默认设置为可空。

由于 IMO,没有简单的方法来保持原始列的可空性。也许您可以尝试查看 UserDefinedTypes 并构建自己的、保留源属性的 DecimalType ?但 IMO 的可空性并非没有原因,我们会尊重这一点,以避免在管道中迟早出现一些糟糕的意外。

关于apache-spark - Spark : cast decimal without changing nullable property of column,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50854815/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com