2016-04-17 12 views
3

を捨てる:Scalaのスパーク - 私は、次のマップを持って空のキー

val pairs = lines.map(l => (if (l.split(",")(1).toInt < 60) { "rest" } else if (l.split(",")(1).toInt > 110) { "sport" }, 10)).reduceByKeyAndWindow((a:Int, b:Int) => (a+b), Seconds(12)) 

誰かのHRは60怒鳴るときに110をスポーツとして分類されている上、基本的に、それは、残りの部分に分類されます。タプルの2番目の変数は、その人が10分間それをやっていることを表します。

ここで、これは60から110までの値の空のキーをマップします。私が望むのは、それらを完全に破棄することです。それはどのように達成可能ですか?

ので

("rest", 30) 
("sport", 120) 
((),10) 

から私は((),10)をフィルタリングしようとしています。 試しました

pairs.filter{case (key, value) => key.length < 3} //error: value length is not a member of Any 
pairs.filter(_._1 != "") //no error, just still keeps the empty keys, too 

どれも動作していません。

+1

フラットマップはあなたの友人です。 – maasg

+0

あなたは細かいことが分かりますか? :) –

+1

申し訳ありません、電話で。 Scalaのフラットマップをここで検索してください。これは以前に議論されている。 – maasg

答えて

1

あなたの問題は、の式が、Unitの場合にはStringを返します。あなたのfilter簡単に修正することができます:Scalaでは

val pairs = lines.map(
    l => (if (l.split(",")(1).toInt < 60) {"rest"} else if (l.split(",")(1).toInt > 110) {"sport"}, 10)) 
    .filter(_._1 !=()) 

()はタイプUnitのアイデンティティです。

しかし、これは正しい方法ではありません。結果としてまだ(Unit, Int)のタプルが得られます。あなたはこのifステートメントでタイプを失っています。

正しい方法は、前にデータをフィルタリングするかのいずれかであるとif網羅を持っている:

val pairs = 
    lines.map(_.split(",")(1).toInt) 
    .filter(hr => hr < 60 || hr > 110) 
    .map(hr => (if (hr < 60) "rest" else "sport", 10)) 

またはそのspark is the shortcut for.filter.mapで、collectを使用する:

val pairs = 
    lines.map(_.split(",")(1).toInt) 
    .collect{ 
     case hr if hr < 60 => "rest" -> 10 
     case hr if hr > 110 => "sport" -> 10 
    } 

おそらく、この変形をより読みです。

また、splitを別々の手順に移動した方法にも注意してください。これは、ブランチの2番目の場合にsplit秒を呼び出すことを避けるために行われます。

UPD。別のアプローチは、コメントで示唆したように、flatMapを使用することです:

それはよく、またはそれは filterステップを回避できますが、ラッピングや Optionでアンラップの要素を追加して、より効率的ではないかもしれない
val pairs = 
    lines.flatMap(_.split(",")(1).toInt match{ 
     case hr if hr < 60 => Some("rest" -> 10) 
     case hr if hr > 110 => Some("sport" -> 10) 
     case _ => None 
    }) 

。さまざまなアプローチのパフォーマンスをテストし、結果を教えてください。

0

注:この質問に直接答えはありません。しかし、それはデータフレームでデータフレーム

を使用して、ユーザーに役立つかもしれないが、我々はこの場合、指定された列

の値が含まれていない行を削除するにはdrop機能を使用することができ、あなたはsc.parallelizeとtoDFを使用することができますデータフレームを構築する。そして、あなたはdfを使うことができます。ドロップ()

関連する問題