我在Spark中有以下几行代码 -
var y = f.join(varietyFrac).map{case(name,(frac,varietyFrac))=>(name,pow((frac.toDouble*varietyFrac.toDouble),0.01)/0.01)}
var num = y.values.collect()
其中y具有以下数据格式 -
org.apache.spark.rdd.RDD[(String, Double)] = MappedRDD[52]
并且有23518行。我在spark
中使用变量num
进行此操作
y.map{case(k,v)=>(k,(num.filter(_<=v).length.toDouble/num.length.toDouble))}.
收集条款的行数似乎很慢。收集约需3分钟。我尝试使用y.values作为RDD而没有转换,但是当我尝试检索值时,我得到以下错误 -
org.apache.spark.SparkException: RDD transformations and actions can only be invoked by the driver, not inside of other transformations
关于如何优化这一点的任何意见或想法都会很棒!提前谢谢!
答案 0 :(得分:1)
正如您所注意到的,您无法在其他转换中引用RDD。当您的数据足够小时,在本地收回其中一个RDD的结果然后使用本机集合可以很好地工作(正如您已经发现的那样)。通过使用Spark的广播设施可以找到进一步的优化。此外,由于您多次计算y,因此缓存y将能够避免重复计算。此外,由于您反复过滤nums上小于某个值的值,因此排序(在驱动程序中)然后使用排序版本+二进制搜索对于您的用例可能更快。希望有所帮助:)