Spark dynamic DAG намного медленнее и отличается от жестко закодированного DAG

У меня есть операция в спарк, которая должна быть выполнена для нескольких столбцов в кадре данных. Как правило, есть 2 возможности указать такие операции

жёстко
handleBias("bar", df)
  .join(handleBias("baz", df), df.columns)
  .drop(columnsToDrop: _*).show
динамически генерировать их из списка имен
var isFirst = true
var res = df
for (col <- columnsToDrop ++ columnsToCode) {
  if (isFirst) {
    res = handleBias(col, res)
    isFirst = false
  } else {
    res = handleBias(col, res)
  }
}
res.drop(columnsToDrop: _*).show

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

Мне любопытно каксочетать элегантность динамичной конструкции с быстрым временем выполнения.

Вот сравнение для групп DAG примера кода

Для около 80 столбцов это приводит к довольно хорошему графику для жестко закодированного вариантаИ очень большой, возможно, менее распараллеливаемый и значительно более медленный DAG для динамически сконструированного запроса.

Текущая версия spark (2.0.2) использовалась сDataFrames и искра-sql

Код для завершения минимального примера:

def handleBias(col: String, df: DataFrame, target: String = "FOO"): DataFrame = {
  val pre1_1 = df
    .filter(df(target) === 1)
    .groupBy(col, target)
    .agg((count("*") / df.filter(df(target) === 1).count).alias("pre_" + col))
    .drop(target)

  val pre2_1 = df
    .groupBy(col)
    .agg(mean(target).alias("pre2_" + col))

  df
    .join(pre1_1, Seq(col), "left")
    .join(pre2_1, Seq(col), "left")
    .na.fill(0)
}
редактировать

Выполнение вашей задачи сfoldleft генерирует линейный DAGи жесткое кодирование функции для всех столбцов приводит к

И то, и другое намного лучше, чем мои оригинальные DAG, но все же вариант в жестком коде выглядит лучше для меня. Конкатенация строк в SQL-выражении в spark может позволить мне динамически генерировать жестко запрограммированный граф выполнения, но это выглядит довольно уродливо. Видите ли вы какой-либо другой вариант?

Ответы на вопрос(1)

Ваш ответ на вопрос