Искра: получение кумулятивной частоты из значений частоты
На мой вопрос довольно просто ответить в среде с одним узлом, но я не знаю, как сделать то же самое в распределенной среде Spark. Теперь у меня есть "частотный график", в котором для каждого элемента у меня есть количество раз, когда оно встречается. Например, это может быть что-то вроде этого: (1, 2), (2, 3), (3,1)
это означает, что 1 произошло 2 раза, 2 3 раза и так далее.
То, что я хотел бы получить, является кумулятивной частотой для каждого элемента, поэтому результат, который мне нужен из приведенных выше данных экземпляра: (1, 2), (2, 3+2=5), (3, 1+3+2=6)
,
До сих пор я пытался сделать это с помощью mapPartitions
который дает правильный результат, если есть только один раздел... в противном случае, очевидно, нет.
Как я могу это сделать?
Благодарю. Marco
2 ответа
Я не думаю, что то, что вы хотите, возможно в качестве распределенного преобразования в Spark, если ваши данные не достаточно малы для объединения в один раздел. Функции Spark работают, распределяя задания между удаленными процессами, и единственный способ связаться - использовать действие, которое возвращает какое-то значение, или использовать аккумулятор. К сожалению, распределенные задания не могут прочитать аккумуляторы, они только для записи.
Если ваши данные достаточно малы, чтобы поместиться в памяти одного раздела / процесса, вы можете объединить (1), и тогда ваш существующий код будет работать. Если нет, но один раздел поместится в памяти, то вы можете использовать локальный итератор:
var total = 0L
rdd.sortBy(_._1).toLocalIterator.foreach(tuple => {
total = total + tuple._2;
println((tuple._1, total)) // or write to local file
})
Если я правильно понял ваш вопрос, он действительно выглядит как подгонка для одной из функций комбинатора - взгляните на разные версии функций aggregateByKey или lowerByKey, которые находятся здесь.