Spark dataframe: подход объединения для производных столбцов - PullRequest
0 голосов
/ 11 сентября 2018

Учитывая набор данных, как вы видите в приведенном ниже коде (df), я должен иметь возможность добавить производный столбец (DerivedCol).Значение этого столбца является константой для группы idcol строк и выводится путем применения а) предиката для значения другого столбца (filter здесь), а затем б) функции агрегирования (max используется здесь) по сопоставлениюgroup.

val df = Seq(("id1","k1","7"),("id2","k1","5"),("id1","k3","2"),("id3","k1","4"),("id2","k5","1"),("id4","k5","1"))
  .toDF("idcol","keycol","valcol")

val aggDf = df.filter($"keycol" === "k1")
  .select($"idcol",$"valcol")
  .groupBy($"idcol")
  .agg(max($"valcol".cast(IntegerType)).cast(StringType).as("DerivedCol"))
  .withColumnRenamed("idcol", "newidcol")

df.join(aggDf, df("idcol") === aggDf("newidcol"), "left_outer")
  .drop(aggDf("newidcol"))

Я использую left outer join для этого.Мой набор данных очень большой (миллионы строк).У меня есть следующие вопросы:

  1. Есть ли другой подход для достижения этой цели?
  2. Какую логику разделения я должен использовать для уменьшения перемешивания?

Мощность столбца idcol очень высока.Версия Spark 2.1.1.

1 Ответ

0 голосов
/ 11 сентября 2018

Есть ли другой способ добиться этого?

Есть - оконные функции.

import org.apache.spark.sql.functions.max
import org.apache.spark.sql.expressions.Window

df.withColumn(
   "derivedcol",  
   max($"valcol".cast(IntegerType)).over(Window.partitionBy($"idcol")
)

В зависимости от:

  • Количество элементов - высокая мощность - это хорошо.
  • Распределение размеров групп - небольшие группы без больших положительных перекосов хороши.

это может вести себя несколько лучше или намного хуже, чем агрегация с последующим объединением.

Чтологику разбиения я должен использовать, чтобы уменьшить перемешивание?

Вероятно, нет.Есть как минимум две причины:

  • Если у вас большое количество небольших групп, то с оконными функциями все будет в порядке, и нет необходимости в дополнительном разбиении.
  • Если у вас небольшое количестводанные больших групп должны транслироваться, и единственное, что требуется для перемешивания, - это агрегация.
  • Если имеется большое количество больших групп - вы можете рассмотреть возможность предварительного разделения по идентификатору, но в зависимости от количества факторов вы можетекак на лугу, так и на усилении, и никакое дополнительное перемешивание (разбиение) в среднем лучше
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...