2016-03-02 2 views
0

У меня есть spark.rdd.RDD[String] MapPartition, который я создал с фильтром.Spark - Rdd String Cleaning/Manipulation

val myMapPartition = myTextFile.filter(_.split("\t")(2) == "\"red\"") 

Этот фильтр разделить мое Textfile линию на вкладку разделитель и проверяется, равно ли второй элемент результирующего массива «красным»

myMapPartition.collect() возвращает Array типа String. Вот пример:

24344 "someString" "red" 
23421 "someOtherString" "red" 

Я пытаюсь выполнить некоторые изменения в строках. В конечном счете, я искал логику замены строк, но сначала попытался объединить строку. Так что я бы искал что-то вроде этого:

24344 "someString hello" "red" 
23421 "someOtherString hello" "red" 

Я попытался сделать это с помощью map:

val myCleanRdd = myMapPartition.map(_1 => (_1.concat(" hello"))) 

Однако, я закончил с:

24344 "someString" "red" hello 
23421 "someOtherString" "red" hello 

Мой вопрос как я могу манипулировать некоторыми элементами строки rdd? Я думаю, проблема в том, что мои строки считаются одной String. Я не уверен, как правильно сопоставить это, чтобы я мог сосредоточиться на отдельных полях.

ОТКАЗ: Scala/Спарк нуб

ответ

2

Сначала необходимо отобразить split по каждому элементу исходного РДУ, так что вы в конечном итоге с RDD[Array[String]], а не как, например RDD[String]

myTextFile.map(_.split("\t")).filter(_(2) == "\"red\"") 

В настоящее время вы используете split для фильтрации входного сигнала RDD цепочек, но это только создает выход РДД цепочек, выбрасывая работу, которую вы сделали, чтобы split их.

Затем, если каждый элемент вашего РДА является Array[String] известной длины, то вы можете map, используя поиск по шаблону (с использованием case ключевого слова) для извлечения и изменять отдельные элементы, например:

rdd.map { case Array(x, y, z) => Array(x, y + " hello", z) } 

(Обратите внимание, что вы должны использовать фигурные скобки {}, а не круглые скобки () вокруг вашей функции map при использовании этого подхода). Подобное сопоставление шаблонов может быть выполнено для строк, которые являются списками, кортежами, векторами и т. Д.

Обновление: если вы хотите заменить один из элементов обработанной версией, это аналогичный шаблон, например.

rdd.map { case Array(x, y, z) => Array(x, y.replace("s","x"), z) } 

Чтобы распечатать все элементы в RDD[Array[String]] вы можете сделать вложенный foreach, например,

rdd.foreach(_.foreach(println)) 

Распечатка каждой строки в массив сложнее, чем ожидалось, из-за перегруженных методов (один обычно используют Arrays.toString но seems to cause type problems в Scala), но может быть сделано следующим образом:

rdd.foreach(row => println(row.mkString("[",",","]"))) 
+0

Именно то, что я искал! Две вещи: Не могли бы вы обсудить, как применить этот шаблон к чему-то вроде функции stringReplace? Кроме того, как только я получу исходный красный цвет 'Array [String]', как я могу его распечатать? Прямо сейчас я просто вижу адреса памяти? Благодаря! –

+0

См. Мои обновления к ответу. – DNA