在另一个窗口内创建窗口?

时间:2019-10-09 09:48:53

标签: dataframe apache-spark

我有一个这样的数据框

+----+-----+
|name|value|
+----+-----+
|   A|    7|
|   A|    5|
|   A|    1|
|   A|    1|
|   A|    1|
|   A|    6|
|   A|    1|
|   A|    1|
|   A|    1|
|   B|    2|
|   B|    1|
+----+-----+

我想将其转换为具有以下值的数据框:

+----+-----+
|name|value|
+----+-----+
|   A|    7|
|   A|    5|
|   A|    5|
|   A|    5|
|   A|    5|
|   A|    6|
|   A|    6|
|   A|    6|
|   A|    6|
|   B|    2|
|   B|    2|
+----+-----+

实际上,我想通过name字段上的分区创建一个窗口,然后在其中创建一个窗口(或类似的东西?),该窗口从当前行的value开始,将以下行的数据分组,直到出现一个非一个值为止。

我该怎么做?

1 个答案:

答案 0 :(得分:-1)

基于@Manish关于注释的想法,我将1的值更改为null,并添加了一个order列,该列唯一地指示行的顺序。

+----+-----+-----+
|name|order|value|
+----+-----+-----+
|   A|    1|    7|
|   A|    2|    5|
|   A|    3| null|
|   A|    4| null|
|   A|    5| null|
|   A|    6|    6|
|   A|    7| null|
|   A|    8| null|
|   A|    9| null|
|   B|   10|    2|
|   B|   11| null|
+----+-----+-----+

然后将last方法与ignorenulls参数一起使用即可解决问题。

win1 = Window.partitionBy("name").orderBy("order")
s = F.last(d.value, ignorenulls = True).over(win1)

d = d.withColumn(
    'value1',
    F.when(
        d.name == F.lag('name').over(win1),
        s
    ).otherwise(s)
)

d.show()

+----+-----+-----+
|name|order|value|
+----+-----+-----+
|   B|   10|    2|
|   B|   11|    2|
|   A|    1|    7|
|   A|    2|    5|
|   A|    3|    5|
|   A|    4|    5|
|   A|    5|    5|
|   A|    6|    6|
|   A|    7|    6|
|   A|    8|    6|
|   A|    9|    6|
+----+-----+-----+