scala - SparkSQL 函数需要类型为 Decimal

标签 scala types apache-spark apache-spark-sql

我设计了以下函数来处理任何数字类型的数组:

def array_sum[T](item:Traversable[T])(implicit n:Numeric[T]) = item.sum
// Registers a function as a UDF so it can be used in SQL statements.
sqlContext.udf.register("array_sumD", array_sum(_:Seq[Float]))

但是想要传递一个 float 类型的数组会出现以下错误:
// Now we can use our function directly in SparkSQL.
sqlContext.sql("SELECT array_sumD(array(5.0,1.0,2.0)) as array_sum").show

错误:
 cannot resolve 'UDF(array(5.0,1.0,2.0))' due to data type mismatch: argument 1 requires array<double> type, however, 'array(5.0,1.0,2.0)' is of array<decimal(2,1)> type;

最佳答案

Spark-SQL 中十进制值的默认数据类型是十进制。如果您 Actor 将查询中的文字转换为浮点数,并使用相同的 UDF,它可以工作:

sqlContext.sql(
  """SELECT array_sumD(array(
    |  CAST(5.0 AS FLOAT),
    |  CAST(1.0 AS FLOAT),
    |  CAST(2.0 AS FLOAT)
    |)) as array_sum""".stripMargin).show

结果,如预期:
+---------+
|array_sum|
+---------+
|      8.0|
+---------+

或者 ,如果您确实想使用小数(以避免浮点问题),您仍然必须使用强制转换来获得正确的精度,而且您将无法使用 Scala 的好 Numericsum , 因为小数读作 java.math.BigDecimal .所以 - 你的代码将是:
def array_sum(item:Traversable[java.math.BigDecimal]) = item.reduce((a, b) => a.add(b))

// Registers a function as a UDF so it can be used in SQL statements.
sqlContext.udf.register("array_sumD", array_sum(_:Seq[java.math.BigDecimal]))

sqlContext.sql(
  """SELECT array_sumD(array(
    |  CAST(5.0 AS DECIMAL(38,18)),
    |  CAST(1.0 AS DECIMAL(38,18)),
    |  CAST(2.0 AS DECIMAL(38,18))
    |)) as array_sum""".stripMargin).show

关于scala - SparkSQL 函数需要类型为 Decimal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36009273/

相关文章:

scala - 覆盖方法并添加隐式参数

c++ - 关于 "casting"变量的快速建议?非常短的功能需要调整

我可以从 C 中的变量中检索数据类型吗?

dataframe - 在 Spark 中重新分区更改 Dataframe 的行顺序

scala - Spark 在 hdfs 上写入 Parquet

java - 规范中未定义任何操作!在swagger ui中指定多个路径时

Scalaz - 无法取消应用类型 StateT[Future, Foo, Bar]

java - 集成 Atmosphere(版本 1.0.13)所需的 java/scala 配置是什么?

c# - 将 .txt 文件解析为不同的数据类型

scala - 将 Word2VecModel 与 UserDefinedFunction 结合使用时出现 NullPointerException