我有一个包含10列的文件。提取前3列或特定列的最优雅方法是什么?
例如,这就是我的文件的样子:
john,smith,84,male,kansas
john,doe,48,male,california
tim,jones,22,male,delaware
我想提取到这个:
[john, smith, kansas]
[john, doe, california]
[tim, jones, delaware]
我拥有的是这个,但它没有专门选择我想要的列:
JavaRDD<String> peopleRDD = sc.textFile(DATA_FILE);
peopleRDD.cache().map(lines -> Arrays.asList(lines.split(",")))
.forEach(person -> LOG.info(person));
我阅读了following two Stackoverflow帖子,但我仍然无法决定如何执行此操作。
修改 我最终做了以下事情:
JavaRDD<String> peopleRDD = sc.textFile(DATA_FILE);
peopleRDD.cache().map(lines -> Arrays.asList(new String[]{lines.split(",")[0],
lines.split(",")[1],
lines.split(",")[3]}
.forEach(person -> LOG.info(person));
不是最优雅的解决方案,但如果您有更好的方法,请在此处发布。感谢。
答案 0 :(得分:1)
编辑:抱歉,我刚刚意识到你要求使用Java解决方案,但我使用过Scala。只有我的第三个建议在Java中有一个等价物(在答案的底部添加)...但是Scala中的Spark确实更好: - )
一种方法是执行split
,然后对结果进行模式匹配,以选择所需的列:
peopleRDD.cache().map(_.split(",") match { case Array(a,b,_,_,e) => List(a,b,e) })
另一个(取决于您想要的元素组合)是使用take
和drop
,使用val
来避免重复分割。
peopleRDD.cache().map{ line =>
val parts = line.split(",")
parts.take(2) ++ parts.drop(4)
}
(如果您想为RDD中的每个结果元素toList
而不是split
,则可以在List
之后添加Array
实际上,可以使用相同的方法来简化原始解决方案,例如:
peopleRDD.cache().map{ line =>
val parts = line.split(",")
List(parts[0], parts[1], parts[4])
}
在Java8中,你可以做同等的,这是一个小小的改进,因为我们避免反复调用split
- 如:
peopleRDD.cache().map( line -> {
Array<String> parts = line.split(",");
Arrays.asList(new String[]{parts[0], parts[1], parts[4]});
})