Spark Scala scala.util.control.Exception在地图中捕获和删除无

时间:2014-11-11 19:19:06

标签: scala exception-handling apache-spark rdd

我正在scala中编写Spark应用程序并希望处理脏输入文件。

// CSV file
val raw_data = sc.textFile(...)

val clean_data = raw_data.map(_.split(delimiter))
  .map( r => (r(0), r(1).toDouble)
当r(1)不是数字时,

将抛出NumberFormatException。这发生在丑陋的输入数据中的少量行上。

我终于以一种丑陋的方式完成了我的需要:

import scala.util.control.Exception._

val clean_data = raw_data.map(_.split(delimiter))
  .map( r => (r(0),
        catching(classOf[NumberFormatException]).opt(r(1).toDouble))
  .filter( r => r._2 != None)
  .map( r => (r._1, r._2.get))

这给我留下两个问题。

1)在地图中简单地删除格式错误的行的最佳方法是什么?

2)如何处理通过捕获创建的Option类型,而无需先显式过滤掉None,然后在非None Option值上映射和应用.get函数?

我尝试应用.flatMap(身份)步骤来摆脱Nones,但得到了预期:TraversableOnce [?]异常。

1 个答案:

答案 0 :(得分:4)

在Spark中collect(pf:PartialFunction)是scala集合collect的双胞胎兄弟,它正是为了这个目的而存在的:保留集合函数中定义的集合元素。

val rawData = sc.textFile(...)

val cleanData = rawData.map(_.split(Delimiter))
             .collect{ case Array(x,y) if (Try(y.toDouble).isSuccess) (x,y.toDouble) }

另一个不评估.toDouble两次的选项是使用flatMap:

val cleanData = rawData.map(_.split(Delimiter))
                       .flatMap(entry => Try(entry.toDouble).toOption)

注意:在Spark中有一点令人困惑的是,有一个无参数collect方法,用于将数据从RDD传送到驱动程序。