【问题标题】:How to overcome java.lang.ArrayIndexOutOfBoundsException error如何克服 java.lang.ArrayIndexOutOfBoundsException 错误
【发布时间】:2016-01-10 03:36:04
【问题描述】:

我映射了从文本文件中获取的数据。文本文件应该有 5 列。例如

29000000    1   0   2013    1   single-sex
29000000    1   0   2013    1   education
29000000    1   0   2013    1   and
29000000    1   0   2013    1   the
29000000    1   0   2013    1   brain

在我的过程中,我只需要出现在第 0 列和第 5 列的值。所以为了得到那些我写了以下内容:

val emp = 
  sc.textFile("\\.txt")
    .map{line => val s = line.split("\t"); (s(5),s(0))}

但是,有时某些行的第 5 列可能不存在,我得到了

15/10/12 17:19:33 INFO TaskSetManager:在执行程序 localhost 的阶段 0.0 (TID 27) 中丢失任务 27.0:java.lang.ArrayIndexOutOfBoundsException (5)

那么在我的映射中,如果 s(5) 存在与否,我应该如何编写 if 条件?

【问题讨论】:

  • 在这种情况下,您的应用程序的业务逻辑需要您做什么?我的意思是,您应该忽略这些记录还是应该以不同的方式行事?
  • 您似乎知道数组是从零开始的,并且由于它们是五个项目,这意味着索引是0, 1, 2, 3, 4。 5 表示第六行。
  • 我的帖子中有 6 个字段。铍的方法效果很好。

标签: scala apache-spark


【解决方案1】:

您可以在两者之间添加filter()

val rdd = 
  sc.textFile("...").map(_.split("\t")).filter(_.size > 5).map(a => (a(0), a(5)))

使用flatMap 的另一个选项(结合“on-the-fly”提取):

val rdd = sc.textFile("...").flatMap { l => 
  l.split("\t") match {
    case Array(x: String, _, _, _, _, y: String) => Some((x, y))
    case _ => None 
  }
}

条件也可以用 guard 表示(连同Array[String] 类上的模式匹配:

val rdd = sc.textFile("...").flatMap { l => 
  l.split("\t") match {
    case a: Array[String] if a.size > 5 => Some((a(0), a(5)))
    // Only one column, provide a default for the other
    case a: Array[String] if a.size == 1 => Some((a(0), "default value"))
    // Ignore everything else
    case _ => None 
  }
}

flatMap 的情况下,您可以将任意数量的不匹配行作为单独的情况处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多