3

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))

これにより、2 つの質問が残ります。

1) 不正な行をマップに単純にドロップする最良の方法は何ですか?

2) 最初に明示的に None を除外してから、None 以外の Option 値に .get 関数をマップして適用する必要なく、キャッチによって作成された Option タイプを処理するにはどうすればよいですか?

Nones を取り除くために .flatMap(identity) ステップを適用しようとしましたが、予期された: TraversableOnce[?] 例外が発生しました。

4

1 に答える 1

4

In Sparkcollect(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) }

2 回評価しない別のオプションは、.toDoubleflatMap を使用することです。

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

collect注: Spark では、RDD からドライバーにデータを取得するためのパラメーターなしのメソッドがあるため、少し混乱します。

于 2014-11-11T23:48:03.533 に答える