2016-05-11 3 views
0

Я видел этот вопрос на StackOverflow, заданный другим пользователем, и я попытался написать код себе, как я пытаюсь практиковать и искру Scala:Свечи Mapvalues ​​против Карта

Вопрос в том, чтобы найти ключ в- средний из списка:

Предполагая, что список является: ((1,1), (1,3), (2,4), (2,3), (3,1))

код был:

val result = input.combineByKey(
(v) => (v, 1), 
(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1), 
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)). 
map{ case (key, value) => (key, value._1/value._2.toFloat) } 
result.collectAsMap().map(println(_)) 

Так в основном приведенный выше код будет создавать RDD типа [Int, (Int, Int)], где первый Int является ключом, а значение (Int, Int), где первый Int здесь является добавлением всех значений с тем же ключом, а второй Int - количество раз, когда появился ключ.

Я понимаю, что происходит, но по какой-то причине, когда я переписать код так:

val result = input.combineByKey(
(v) => (v, 1), 
(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1), 
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)). 
mapValues(value: (Int, Int) => (value._1/value._2)) 
result.collectAsMap().map(println(_)) 

Когда я использую mapValues ​​вместо карты с case ключевым словом код не work.It дает ошибку: error: not found: type / В чем разница при использовании карты с футляром и mapValues. Поскольку я думал, что значения карты будут просто принимать значение (которое в этом случае является (Int, Int)) и возвращать вам новое значение, а ключ остается неизменным для пары значений ключа.

+0

Возможный дубликат [карты против mapValues ​​в Спарк] (https://stackoverflow.com/questions/36696326/map-vs-mapvalues-in-spark) –

ответ

1

попробовать

val result = input.combineByKey(
(v) => (v, 1), 
(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1), 
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)). 
mapValues(value => (value._1/value._2)) 
result.collectAsMap().map(println(_)) 
+0

Ох уж этот работал хорошо ! Почему вам не нужно значение value: (Int, Int) '? Я также сделал это, и он работал: 'result.map (elem => (elem._1, (elem._2._1/elem._2._2))). CollectAsMap(). Map (println (_))' – CapturedTree

+0

@ 1290 Я не знаю точного ответа, но вам не нужно явно указывать тип данных rdd в искровых преобразованиях/действиях. – banjara

+0

О, ладно, я вижу. Благодаря! – CapturedTree

Смежные вопросы