Как использовать row_number() на основе условия в spark с помощью scala

#scala #apache-spark #apache-spark-sql #window-functions

#scala #apache-spark #apache-spark-sql #окно-функции

Вопрос:

У меня есть приведенный ниже фрейм данных —

  ---- ----- --- 
| val|count| id|
 ---- ----- --- 
|   a|   10| m1|
|   b|   20| m1|
|null|   30| m1|
|   b|   30| m2|
|   c|   40| m2|
|null|   50| m2|
 ---- ----- --- 
 

создано —

  val df1=Seq(
 ("a","10","m1"),
 ("b","20","m1"),
 (null,"30","m1"),
 ("b","30","m2"),
 ("c","40","m2"),
 (null,"50","m2")
 )toDF("val","count","id")
 

Я пытаюсь создать ранг с помощью row_number() и функции окна, как показано ниже.

 df1.withColumn("rannk_num", row_number() over Window.partitionBy("id").orderBy("count")).show
 ---- ----- --- --------- 
| val|count| id|rannk_num|
 ---- ----- --- --------- 
|   a|   10| m1|        1|
|   b|   20| m1|        2|
|null|   30| m1|        3|
|   b|   30| m2|        1|
|   c|   40| m2|        2|
|null|   50| m2|        3|
 ---- ----- --- --------- 
 

Но я должен фильтровать эти записи с нулевыми значениями для столбца — val.

Ожидаемый результат —

  ---- ----- --- --------- 
| val|count| id|rannk_num|
 ---- ----- --- --------- 
|   a|   10| m1|        1|
|   b|   20| m1|        2|
|null|   30| m1|     NULL|
|   b|   30| m2|        1|
|   c|   40| m2|        2|
|null|   50| m2|     NULL|
 ---- ----- --- --------- 
 

интересно, возможно ли это с минимальными изменениями. Также может быть ‘n’ значений для столбцов val и count.

Ответ №1:

Отфильтруйте эти строки с нулевым значением, присвоите им нулевой номер строки и объедините обратно в исходный фрейм данных.

 val df1=Seq(
 ("a","10","m1"),
 ("b","20","m1"),
 (null,"30","m1"),
 ("b","30","m2"),
 ("c","40","m2"),
 (null,"50","m2")
 ).toDF("val","count","id")

df1.filter("val is not null").withColumn(
    "rannk_num", row_number() over Window.partitionBy("id").orderBy("count")
).union(
    df1.filter("val is null").withColumn("rannk_num", lit(null))
).show
 ---- ----- --- --------- 
| val|count| id|rannk_num|
 ---- ----- --- --------- 
|   a|   10| m1|        1|
|   b|   20| m1|        2|
|   b|   30| m2|        1|
|   c|   40| m2|        2|
|null|   30| m1|     null|
|null|   50| m2|     null|
 ---- ----- --- --------- 
 

Комментарии:

1. Существует ли какой-либо механизм фильтрации по умолчанию на уровне фрейма данных при создании самого row_number()

2. фильтрация не выполняется, поскольку предполагается, что row_number присваивает номер строки каждой отдельной строке.