问题描述
我正在尝试类似的事情
val df = Seq((50984908,1000)).toDF("x","y")
val myExpression = "x * y"
df.withColumn("z",expr(myExpression)).show()
我可以看到它导致整数溢出,并且不会被强制转换为Long
+--------+----+----------+
| x| y| z|
+--------+----+----------+
|50984908|1000|-554699552|
+--------+----+----------+
有人可以提供建议如何避免这些溢出吗? 有没有一种方法可以使Spark正确地自动推断出更高的精度(例如:整数->长整数),(浮点数-> Double / BigDecimal)?
解决方法
在Scala中,您可以通过添加后缀L
将数字文字显式声明为Long。如果这样做,类型将正确推断为Long
:
val df = Seq((50984908L,1000L)).toDF("x","y")
val myExpression = "x * y"
df.withColumn("z",expr(myExpression)).show()
如果您需要对列类型进行更多控制,则还可以使用函数createDataFrame
:
import org.apache.spark.sql.types._
import org.apache.spark.sql.Row
val someData = Seq(
Row(50984908L,1000L)
)
val myExpression = "x * y"
val someSchema = List(
StructField("x",LongType,true),StructField("y",true)
)
val df = spark.createDataFrame(
spark.sparkContext.parallelize(someData),StructType(someSchema)
)
df.withColumn("z",expr(myExpression)).show()