运行“stats()”的 Spark 错误:找不到参数 num 的隐式值:Numeric [Double]
Posted
技术标签:
【中文标题】运行“stats()”的 Spark 错误:找不到参数 num 的隐式值:Numeric [Double]【英文标题】:Spark Error Running "stats()": could not find implicit value for parameter num: Numeric[Double] 【发布时间】:2017-11-09 02:54:25 【问题描述】:刚写了一些 MapReduce 作业后,我正在学习 spark/scala。
我写了一些 java bean 来帮助我在 HDFS 中解析一个文件,我想用它来帮助加快我在 spark 中的进度。
我已经成功加载了我的文件并创建了一个 java bean 对象数组:
val input = sc.textFile("hdfs://host:port/user/test/path/out")
import my.package.Record
val clust_recs = clv_input.map(line => new my.package.Record(line))
clust_recs.map(rec => rec.getPremium()).stats()
但是最后一行会产生这个错误:
<console>:46: error: could not find implicit value for parameter num: Numeric[Double]
我已经测试了这个字段中的值都是有效的,所以我很确定我没有任何可能导致这个错误的空值。
这是一个值的例子:
val dblArray = clust_recs.map(rec => rec.getPremium()).filter(!isNaN(_))
dblArray.take(10)
输出:
res82: Array[Double] = Array(1250.6, 433.72, 567.07, 219.24, 310.32, 2173.48, 195.0, 697.94, 711.46, 42.718050000000005)
我不知道如何解决这个错误,想知道我是否应该放弃使用我已经创建的 JavaBean 对象的概念。
【问题讨论】:
my.package.Record
是案例类吗?
不,my.package.Record 是一个 Java 类(传统的 java bean,带有 getter 和 setter)
Record.getPremium()
的签名是什么?
什么是 Spark 版本?
【参考方案1】:
您只能通过隐式转换 RDD[Double]
或 RDD[T]
来期望 stats
运算符在 RDD[T]
上可用,其中 T
可以转换为 Numeric[T]
(请参阅 the code):
implicit def doubleRDDToDoubleRDDFunctions(rdd: RDD[Double]): DoubleRDDFunctions =
new DoubleRDDFunctions(rdd)
implicit def numericRDDToDoubleRDDFunctions[T](rdd: RDD[T])(implicit num: Numeric[T])
: DoubleRDDFunctions =
new DoubleRDDFunctions(rdd.map(x => num.toDouble(x)))
DoubleRDDFunctions的scaladoc中也提到了隐式转换:
通过隐式转换在 Doubles 的 RDD 上可用的额外函数。
关键是下面这行没有给你RDD[Double]
,而是别的东西。
clust_recs.map(rec => rec.getPremium())
这就是下面编译错误的原因:
错误:找不到参数 num 的隐式值:Numeric[Double]
Scala 编译器找不到称为num
的Numeric[Double]
隐式转换。
implicit def numericRDDToDoubleRDDFunctions[T](rdd: RDD[T])(implicit num: Numeric[T])
: DoubleRDDFunctions =
new DoubleRDDFunctions(rdd.map(x => num.toDouble(x)))
我只能猜测 Double
是 Java 的 java.lang.Double
而不是 Scala 的 Double
,因此会出现编译错误。
【讨论】:
【参考方案2】:感谢 Jacek 让我找到正确的方向,您的回答让我更多地了解如何在 map 函数中将 java.lang.Double 转换为 scala.Double。
作为 scala 的新用户,我正在努力处理与 Java 的差异,尤其是隐式转换。
我发现这篇文章很有帮助:http://www.scala-archive.org/scala-Double-td1939353.html
并最终将代码更改为:
clust_recs.map(rec => rec.getPremium().doubleValue()).stats()
输出:
res28: org.apache.spark.util.StatCounter = (count: 1000000, mean: 170.636, stdev: 28.13, max: 2180.000000, min: 0.000000)
【讨论】:
以上是关于运行“stats()”的 Spark 错误:找不到参数 num 的隐式值:Numeric [Double]的主要内容,如果未能解决你的问题,请参考以下文章
mysql错误:找不到表“mysql”。“innodb_table_stats”
SparkContext 错误 - 找不到文件 /tmp/spark-events 不存在