Обычные коллекции scala имеют отличный метод collect
, который позволяет мне выполнять операцию filter-map
за один проход, используя частичную функцию. Есть ли эквивалентная операция на spark Dataset
s?
Я хотел бы это по двум причинам:
- синтаксическая простота
- он сокращает операции в стиле
filter-map
до одного прохода (хотя в spark я предполагаю, что есть оптимизации, которые определяют эти вещи для вас)
Вот пример, чтобы показать, что я имею в виду. Предположим, у меня есть последовательность параметров, и я хочу извлечь и удвоить только определенные целые числа (те, что в Some
):
val input = Seq(Some(3), None, Some(-1), None, Some(4), Some(5))
Способ 1 — collect
input.collect {
case Some(value) => value * 2
}
// List(6, -2, 8, 10)
collect
делает это довольно аккуратно синтаксически и выполняет один проход.
Способ 2 — filter-map
input.filter(_.isDefined).map(_.get * 2)
Я могу перенести этот тип шаблона на искру, потому что наборы данных и фреймы данных имеют аналогичные методы.
Но мне это не очень нравится, потому что isDefined
и get
кажутся мне запахом кода. Существует неявное предположение, что карта получает только Some
s. Компилятор не может это проверить. В более крупном примере разработчику будет сложнее обнаружить это предположение, и разработчик может поменять фильтр и сопоставить, например, без получения синтаксической ошибки.
Способ 3 – fold*
операций
input.foldRight[List[Int]](Nil) {
case (nextOpt, acc) => nextOpt match {
case Some(next) => next*2 :: acc
case None => acc
}
}
Я не использовал искру достаточно, чтобы знать, есть ли у fold эквивалент, так что это может быть немного тангенциально.
Как бы то ни было, совпадение шаблона, сгибание шаблона и перестроение списка — все смешалось вместе, и это трудно читать.
Так что в целом я считаю синтаксис collect
самым приятным, и я надеюсь, что у искры есть что-то подобное.
collect
, определенный дляRDD
s иDataset
s, используется для материализации данных в программе-драйвере. Несмотря на отсутствие чего-то похожего на метод Collections APIcollect
, ваша интуиция верна: поскольку обе операции оцениваются лениво, у движка есть возможность оптимизировать операции и связать их так, чтобы они выполнялись с максимальной локальностью. - person stefanobaghino   schedule 25.01.2017