У меня есть DataFrame со столбцом start_date типа даты. Теперь мне нужно сгенерировать метрики для уникальных значений в column1 с start_date раньше или равным. Ниже приведен входной DataFrame

column1   column2  start_date
id1       val1     2018-03-12
id1       val2     2018-03-12
id2       val3     2018-03-12 
id3       val4     2018-03-12
id4       val5     2018-03-11
id4       val6     2018-03-11
id5       val7     2018-03-11
id5       val8     2018-03-11 
id6       val9     2018-03-10 

Теперь мне нужно преобразовать в следующее,

start_date     count
2018-03-12    6
2018-03-11    3
2018-03-10    1 

Это то, что я делаю неэффективно,

  1. обнаружение всех различных start_dates и сохранение в виде списка
  2. перебирать список и генерировать вывод для каждой start_date
  3. объединение всех выходных данных в один фрейм данных.

Есть ли лучший способ сделать это без зацикливания?

0
abhijeet 13 Мар 2018 в 11:45

2 ответа

Лучший ответ

Вы можете совместить стандартную агрегацию с оконной функцией, но второй этап не будет распределен

import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions._


df
 .groupBy($"start_date")
 .agg(approx_count_distinct($"column1").alias("count"))
 .withColumn(
   "cumulative_count", sum($"count").over(Window.orderBy($"start_date")))
1
Alper t. Turker 13 Мар 2018 в 08:59

Попробуйте что-то вроде следующего -

groupBy("start_date").agg(countdistinct("column1"))

Исследуйте этот шаблон

Проверьте countDistinct - https://spark.apache.org/docs/2.3.0/api/scala/index.html#org.apache .spark.sql.functions

Использовать Spark Window - Пример

val df = ... // schema => timestamp: TimestampType, stockId: StringType, price: DoubleType
df.groupBy(window($"time", "1 minute"), $"stockId")
  .agg(mean("price"))
2
Abhishek Choudhary 13 Мар 2018 в 09:02