Spark — Scala: возвращает несколько после обработки одной строки

#scala #apache-spark

#scala #apache-spark

Вопрос:

У меня есть набор данных, который выглядит следующим образом —

0 — 1,2,4
1 — 0,4
2 — 0,4
4 — 2,1,0

Я хочу прочитать каждую строку и преобразовать ее во что-то, что выглядит следующим образом

// для строки 0 — 1,2,4
(0,1) <2,4>
(0,2) <1,4>
(0,4) <1,2>

// для строки 1 — 0,4
(0,1) <4>
(1,4) <0>

// меньшее число всегда появляется первым в паре

т.е. считывает каждую строку, разделенную разделителем «—«. Итак, я получаю 0 и 1,2,4 из строки 1 набора данных. После этого я хочу создать пары. Например, (0,1), который будет ключом для преобразованной карты, и его значение должно быть 2,4.

Как только это будет сделано, я хочу иметь возможность группировать значения по ключу

Например (0,1) <2,4> <4>

и пересекает их, чтобы получить 4.

Возможно ли сделать что-то подобное? Правильный ли мой подход?

Я уже написал приведенный ниже код-

 var mapOperation = logData.map(x=>x.split("t")).filter(x => x.length == 2).map(x => (x(0),x(1)))
// reading file and creating the map Example - key 0 value 1,2,4

//from the first map, trying to create pairs
var mapAgainstValue = mapOperation.map{
line =>
val fromFriend = line._1
val toFriendsList = line._2.split(",")
(fromFriend -> toFriendsList)
}

val newMap = mapAgainstValue.map{
line =>
var key ="";
for(userIds <- line._2){
key =line._1.concat("," userIds);
(key -> line._2.toList)
}

}
  

Проблема в том, что я не могу вызвать groupByKey в newMap. Я предполагаю, что есть какая-то проблема с тем, как я создал карту?

Ценю любую помощь.

Спасибо.

Комментарии:

1. Пожалуйста, отредактируйте вопрос и добавьте больше деталей, поскольку я не могу понять, чего вы на самом деле хотите

2. Я отредактировал вопрос. Надеюсь, это лучше, чем раньше.

Ответ №1:

Ваша проблема может быть решена следующим образом :

  val inputRDD=sc.textFile("inputFile.txt")  
inputRDD.flatMap{a=>
          val list=a.split("--")
          val firstTerm=list(0)
          val secondTermAsList=list(1).split(",")
          secondTermAsList.map{b=>
          val key=if(b>firstTerm) (firstTerm,b) else (b,firstTerm)
          val value=secondTermAsList diff List(b)
          (key,value)
          }
          }
  

Этот код приводит к такому выводу :

  ----- ------ 
|_1   |_2    |
 ----- ------ 
|[0,1]|[2, 4]|
|[0,2]|[1, 4]|
|[0,4]|[1, 2]|
|[0,1]|[4]   |
|[1,4]|[0]   |
|[0,2]|[4]   |
|[2,4]|[0]   |
|[2,4]|[1, 0]|
|[1,4]|[2, 0]|
|[0,4]|[2, 1]|
 ----- ------ 
  

Я надеюсь, что это решит вашу проблему!

Комментарии:

1. Это действительно хороший фрагмент кода. Большое спасибо. Итак, отсюда я должен иметь возможность группировать по ключу и пересекать наборы значений.

2. Еще одна вещь, куда мне следует добавить фильтр, если не каждый элемент в наборе данных имеет значения после разделителя — ?

3. Проверьте, равен ли размер списка после разделения 1 . Если это так, просто укажите значение по умолчанию или выполните вычисления

4. Я не могу добавить условие if, подобное этому — val x = inputRDD.flatMap { a => val list = a.split(» t») if (list.length > 1) { val firstTerm = list(0) val secondTermAsList = list(1).split(«,») secondTermAsList.map { b => val key = if (b.toInt > firstTerm.toInt) (firstTerm, b) else (b , firstTerm) значение val = Список различий secondTermAsList(b) (ключ, значение) } } }

5. Вы должны вычислить if как выражение