Скопируйте пропущенные данные из значений столбцов верхней / нижней строки - PullRequest
0 голосов
/ 15 апреля 2019

У меня есть dataframe, с индексом, категорией и несколькими другими столбцами.Индекс и категория никогда не будут пустыми / нулевыми.но данные других столбцов равны нулю. Когда все остальные данные столбцов равны нулю, мы должны скопировать значения из верхней / нижней строки на основе категрии.

val df = Seq(
  (1,1, null, null, null ), 
  (2,1, null, null, null ), 
  (3,1, null, null, null ), 
  (4,1,"123.12", "124.52", "95.98" ), 
  (5,1, "452.12", "478.65", "1865.12" ), 
  (1,2,"2014.21", "147", "265"), 
  (2,2, "1457", "12483.00", "215.21"), 
  (3,2, null, null, null),
  (4,2, null, null, null) ).toDF("index", "category", "col1", "col2", "col3")


scala> df.show
+-----+--------+-------+--------+-------+
|index|category|   col1|    col2|   col3|
+-----+--------+-------+--------+-------+
|    1|       1|   null|    null|   null|
|    2|       1|   null|    null|   null|
|    3|       1|   null|    null|   null|
|    4|       1| 123.12|  124.52|  95.98|
|    5|       1| 452.12|  478.65|1865.12|
|    1|       2|2014.21|     147|    265|
|    2|       2|   1457|12483.00| 215.21|
|    3|       2|   null|    null|   null|
|    4|       2|   null|    null|   null|
+-----+--------+-------+--------+-------+

Ожидается dataframe, как показано ниже

+-----+--------+-------+--------+-------+
|index|category|   col1|    col2|   col3|
+-----+--------+-------+--------+-------+
|    1|       1| 123.12|  124.52|  95.98|       // Copied from below for same category
|    2|       1| 123.12|  124.52|  95.98|       // Copied from below for same category
|    3|       1| 123.12|  124.52|  95.98|
|    4|       1| 123.12|  124.52|  95.98|
|    5|       1| 452.12|  478.65|1865.12|
|    1|       2|2014.21|     147|    265|
|    2|       2|   1457|12483.00| 215.21|
|    3|       2|   1457|12483.00| 215.21|       // Copied from above for same category
|    4|       2|   1457|12483.00| 215.21|       // Copied from above for same category
+-----+--------+-------+--------+-------+   

1 Ответ

2 голосов
/ 15 апреля 2019

Обновление Если возможно несколько строк с нулевыми значениями, необходимо использовать расширенную версию Windows:

val cols = Seq("col1", "col2", "col3")
val beforeWindow = Window
  .partitionBy("category")
  .orderBy("index")
  .rangeBetween(Window.unboundedPreceding, Window.currentRow)

val afterWindow = Window
  .partitionBy("category")
  .orderBy("index")
  .rangeBetween(Window.currentRow, Window.unboundedFollowing)

val result = cols.foldLeft(df)((updated, columnName) =>
  updated.withColumn(columnName,
    coalesce(col(columnName),
      last(columnName, ignoreNulls = true).over(beforeWindow),
      first(columnName, ignoreNulls = true).over(afterWindow)
    ))
)

В одном пустом случае можно разрешить с помощью оконных функций «лидерство» и «отставание», а также «объединение»:

val cols = Seq("col1", "col2", "col3")
val categoryWindow = Window.partitionBy("category").orderBy("index")

val result = cols.foldLeft(df)((updated, columnName) =>
  updated.withColumn(columnName,
    coalesce(col(columnName),
      lag(col(columnName), 1).over(categoryWindow),
      lead(col(columnName), 1).over(categoryWindow)
    ))
)
result.show(false)

Выход:

+-----+--------+-------+--------+-------+
|index|category|col1   |col2    |col3   |
+-----+--------+-------+--------+-------+
|1    |1       |123.12 |124.52  |95.98  |
|2    |1       |123.12 |124.52  |95.98  |
|3    |1       |452.12 |478.65  |1865.12|
|1    |2       |2014.21|147     |265    |
|2    |2       |1457   |12483.00|215.21 |
|3    |2       |1.25   |3.45    |26.3   |
|4    |2       |1.25   |3.45    |26.3   |
+-----+--------+-------+--------+-------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...