Scala Spark - 丢弃空键

时间:2016-04-17 17:38:16

标签: scala apache-spark

我有以下地图:

CREATE DIRECTORY test_dir AS 'C:\';
GRANT READ, WRITE ON DIRECTORY test_dir TO exporter;

基本上,当某人的HR低于60时,它被归类为休息,110以上被归类为运动。元组的第二个变量表示该人已经做了10分钟。

现在Rigth,这会为60到110之间的值映射一个空键。我想要的是完全丢弃它们。这怎么可以实现?

所以来自

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

我正在尝试过滤掉("rest", 30) ("sport", 120) ((),10) 。 我试过了

((),10)

似乎无效。

2 个答案:

答案 0 :(得分:1)

您的问题是,if表达式会在String与{1}}匹配时返回Unit。您可以轻松修复filter

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

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

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

split

这个变体可能更具可读性。

另外,请注意我如何将split移到单独的步骤中。这样做是为了避免第二次调用flatMap第二次if。

<强> UPD 即可。另一种方法是使用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 }) ,如评论中所示:

filter

它可能会或可能不会更有效率,因为它可以避免Option步骤,但会在INT_MAX中添加包装和展开元素。您可以测试不同方法的表现并告诉我们结果。

答案 1 :(得分:0)

注意:不是这个问题的直接答案。但它对使用数据帧的用户可能有用

在Dataframe中,我们可以使用drop函数删除不包含指定列值的行

在这种情况下,您可以使用sc.parallelize和toDF来构造数据帧。然后你可以使用df.drop()

相关问题