如何在Pyspark中获取组内的下一个非空值

wnavrhmk  于 2023-01-01  发布在  Spark
关注(0)|答案(1)|浏览(177)

我有一个销售事务 Dataframe ,如下所示:

|   id   |  date   |  ammount |last_order_date  |
-------------------------------------------------
|  001   | 2021-01 |    100   |     2020-11     |
|  001   | 2021-02 |      0   |      null       |
|  001   | 2021-03 |      0   |      null       |
|  001   | 2021-04 |     20   |     2021-01     |
|  001   | 2021-05 |      0   |      null       |
|  001   | 2021-06 |      0   |      null       |
|  001   | 2021-07 |      0   |      null       |
|  001   | 2021-08 |     50   |     2021-04     |
-------------------------------------------------
|  002   | 2022-03 |      5   |     2022-01     |
|  002   | 2022-04 |     40   |     2022-03     |
|  002   | 2022-05 |      0   |      null       |
|  002   | 2022-06 |      0   |      null       |
|  002   | 2022-07 |      0   |      null       |
|  002   | 2022-08 |     35   |     2022-04     |

我想用每个组(id)的同一列的下一个非空值替换列last_order_date中的空值,这样我就得到了 Dataframe ;

|   id   |  date   |  ammount |last_order_date  |
-------------------------------------------------
|  001   | 2021-01 |    100   |     2020-11     |
|  001   | 2021-02 |      0   |     2021-01     |
|  001   | 2021-03 |      0   |     2021-01     |
|  001   | 2021-04 |     20   |     2021-01     |
|  001   | 2021-05 |      0   |     2021-04     |
|  001   | 2021-06 |      0   |     2021-04     |
|  001   | 2021-07 |      0   |     2021-04     |
|  001   | 2021-08 |     50   |     2021-04     |
-------------------------------------------------
|  002   | 2022-03 |      5   |     2022-01     |
|  002   | 2022-04 |     40   |     2022-03     |
|  002   | 2022-05 |      0   |     2022-04     |
|  002   | 2022-06 |      0   |     2022-04     |
|  002   | 2022-07 |      0   |     2022-04     |
|  002   | 2022-08 |     35   |     2022-04     |

对于我所发现的方法在于使用last/first函数,同时使用id分区的窗口。然而,当我应用以下代码时:

df.withColumn('last_order_date', F.last('last_order_date', ignorenulls = True).over(Window.partitionBy('id').orderBy('date')))

我得到的空值替换为以前的非空值

|   id   |  date   |  ammount |last_order_date  |
-------------------------------------------------
|  001   | 2021-01 |    100   |     2020-11     |
|  001   | 2021-02 |      0   |     2020-11     |
|  001   | 2021-03 |      0   |     2020-11     |
|  001   | 2021-04 |     20   |     2021-01     |
|  001   | 2021-05 |      0   |     2021-01     |
|  001   | 2021-06 |      0   |     2021-01     |
|  001   | 2021-07 |      0   |     2021-01     |
|  001   | 2021-08 |     50   |     2021-04     |
-------------------------------------------------
|  002   | 2022-03 |      5   |     2022-01     |
|  002   | 2022-04 |     40   |     2022-03     |
|  002   | 2022-05 |      0   |     2022-03     |
|  002   | 2022-06 |      0   |     2022-03     |
|  002   | 2022-07 |      0   |     2022-03     |
|  002   | 2022-08 |     35   |     2022-04     |

我不太清楚问题出在哪里,先谢谢你的帮助。

cygmwpex

cygmwpex1#

你非常接近.如果你使用一个first与你的窗口,但做一个滑动窗口,你可以达到你所需的结果.

import sys
import pyspark.sql.functions as func
from pyspark.sql.window import Window as wd

data_sdf. \
    withColumn('last_order_dt_filled', 
               func.first('last_order_dt', ignorenulls=True).
               over(wd.partitionBy('id').orderBy('dt').rowsBetween(0, sys.maxsize))
               ). \
    show()

# +---+-------+---+-------------+--------------------+
# | id|     dt|amt|last_order_dt|last_order_dt_filled|
# +---+-------+---+-------------+--------------------+
# |001|2021-01|100|      2020-11|             2020-11|
# |001|2021-02|  0|         null|             2021-01|
# |001|2021-03|  0|         null|             2021-01|
# |001|2021-04| 20|      2021-01|             2021-01|
# |001|2021-05|  0|         null|             2021-04|
# |001|2021-06|  0|         null|             2021-04|
# |001|2021-07|  0|         null|             2021-04|
# |001|2021-08| 50|      2021-04|             2021-04|
# |002|2022-03|  5|      2022-01|             2022-01|
# |002|2022-04| 40|      2022-03|             2022-03|
# |002|2022-05|  0|         null|             2022-04|
# |002|2022-06|  0|         null|             2022-04|
# |002|2022-07|  0|         null|             2022-04|
# |002|2022-08| 35|      2022-04|             2022-04|
# +---+-------+---+-------------+--------------------+

其思想是获取从当前行开始到组末尾的第一个非空值。

相关问题