#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 как выражение