Как использовать orderby() с убывающим порядком в функциях окна Spark?
Мне нужна функция окна, которая разделяет некоторые ключи (= имена столбцов), заказы по имени другого столбца и возвращает строки с рангом x.
Это отлично работает для возрастания:
def getTopX(df: DataFrame, top_x: String, top_key: String, top_value:String): DataFrame ={
val top_keys: List[String] = top_key.split(", ").map(_.trim).toList
val w = Window.partitionBy(top_keys(1),top_keys.drop(1):_*)
.orderBy(top_value)
val rankCondition = "rn < "+top_x.toString
val dfTop = df.withColumn("rn",row_number().over(w))
.where(rankCondition).drop("rn")
return dfTop
}
Но когда я пытаюсь изменить его на orderBy(desc(top_value))
или orderBy(top_value.desc)
в строке 4, я получаю синтаксическую ошибку. Какой правильный синтаксис здесь?
Ответы
Ответ 1
Существуют две версии orderBy
, одна из которых работает со строками, а другая - с объектами Column
(API). Ваш код использует первую версию, которая не позволяет изменять порядок сортировки. Вам нужно переключиться на версию столбца, а затем вызвать метод desc
, например, myCol.desc
.
Теперь мы попадаем на территорию дизайна API. Преимущество прохождения параметров Column
заключается в том, что вы обладаете гораздо большей гибкостью, например, вы можете использовать выражения и т.д. Если вы хотите поддерживать API, который принимает строку, а не Column
, вам нужно преобразовать строка в столбец. Существует несколько способов сделать это, и проще всего использовать org.apache.spark.sql.functions.col(myColName)
.
Объединяя все это, получим
.orderBy(org.apache.spark.sql.functions.col(top_value).desc)
Ответ 2
Скажем, например, если нам нужно упорядочить по столбцу с именем Date
в порядке убывания в функции Window, используйте символ $
перед именем столбца, что позволит нам использовать синтаксис asc
или desc
.
Window.orderBy($"Date".desc)
После указания имени столбца в двойных кавычках укажите .desc
, который будет сортироваться в порядке убывания.
Ответ 3
Column col = новый столбец ("ts");
col = col.desc();
WindowSpec w = Window.partitionBy("col1", "col2"). OrderBy (col);