我正在尝试从文本文件中读取字符串,但我想根据特定大小限制每一行。例如;
这是我代表该文件。
AAAAA \ nbbb \ nccccc
当尝试通过sc.textFile读取此文件时,RDD会出现此文件。
scala> val rdd = sc.textFile("textFile")
scala> rdd.collect
res1: Array[String] = Array(aaaaa, bbb, ccccc)
但是我想限制这个RDD的大小。例如,如果限制为3,那么我应该像这样。
Array[String] = Array(aaa, aab, bbc, ccc, c)
这样做的最佳表现方式是什么?
答案 0 :(得分:2)
不是一个特别有效的解决方案(也不是很糟糕),但你可以这样做:
val pairs = rdd
.flatMap(x => x) // Flatten
.zipWithIndex // Add indices
.keyBy(_._2 / 3) // Key by index / n
// We'll use a range partitioner to minimize the shuffle
val partitioner = new RangePartitioner(pairs.partitions.size, pairs)
pairs
.groupByKey(partitioner) // group
// Sort, drop index, concat
.mapValues(_.toSeq.sortBy(_._2).map(_._1).mkString(""))
.sortByKey()
.values
可以通过传递显式填充分区所需的数据来避免混乱,但需要花费一些精力进行编码。请参阅我对Partition RDD into tuples of length n的回答。
如果您可以在分区边界上接受一些未对齐的记录,那么带分组的简单mapPartitions
应该以更低的成本完成这一操作:
rdd.mapPartitions(_.flatMap(x => x).grouped(3).map(_.mkString("")))
也可以使用滑动RDD:
rdd.flatMap(x => x).sliding(3, 3).map(_.mkString(""))
答案 1 :(得分:0)
无论如何,您需要阅读所有数据。除了映射每条线并修剪它之外,你可以做的不多。
rdd.map(line => line.take(3)).collect()