从pyspark的下一列中删除空值并转移值

时间:2020-08-10 14:51:09

标签: pyspark

我需要将Python脚本转换为Pyspark,这对我来说是一项艰巨的任务。

我正在尝试从数据帧中删除空值(而不删除整个列或行),并将下一个值移到上一列。示例:

        CLIENT| ANIMAL_1 | ANIMAL_2 | ANIMAL_3| ANIMAL_4
ROW_1     1   |   cow    | frog     | null    | dog
ROW_2     2   |   pig    | null     | cat     | null

我的目标是:

       CLIENT| ANIMAL_1 | ANIMAL_2 | ANIMAL_3| ANIMAL_4
ROW_1     1   |   cow    | frog     | dog     | null
ROW_2     2   |   pig    | cat      | null    | null

我在python上使用的代码是(我在Stackoverflow上找到了):

df_out = df.apply(lambda x: pd.Series(x.dropna().to_numpy()), axis=1)

然后,我将列重命名。但是我不知道如何在Pyspark上做到这一点。

1 个答案:

答案 0 :(得分:2)

这是针对Spark 2.4+版本执行此操作的一种方法:

创建所需列的数组,并根据以下条件进行排序:

  1. 先排序非空值
  2. 按在列中显示的顺序对值进行排序

我们可以使用array_sort进行排序。要满足多种条件,请使用arrays_zip。为了便于提取所需的值(在此示例中为动物),也压缩了zip列的值。

from pyspark.sql.functions import array, array_sort, arrays_zip, col, lit

animal_cols = df.columns[1:]
N = len(animal_cols)

df_out = df.select(
    df.columns[0],
    array_sort(
        arrays_zip(
            array([col(c).isNull() for c in animal_cols]),
            array([lit(i) for i in range(N)]),
            array([col(c) for c in animal_cols])
        )
    ).alias('sorted')
)
df_out.show(truncate=False)
#+------+----------------------------------------------------------------+
#|CLIENT|sorted                                                          |
#+------+----------------------------------------------------------------+
#|1     |[[false, 0, cow], [false, 1, frog], [false, 3, dog], [true, 2,]]|
#|2     |[[false, 0, pig], [false, 2, cat], [true, 1,], [true, 3,]]      |
#+------+----------------------------------------------------------------+

现在事情以正确的顺序进行,您只需要提取值即可。在这种情况下,这就是'2'列的第i个索引中元素sorted上的项目。

df_out = df_out.select(
    df.columns[0],
    *[col("sorted")[i]['2'].alias(animal_cols[i]) for i in range(N)]
)
df_out.show(truncate=False)
#+------+--------+--------+--------+--------+
#|CLIENT|ANIMAL_1|ANIMAL_2|ANIMAL_3|ANIMAL_4|
#+------+--------+--------+--------+--------+
#|1     |cow     |frog    |dog     |null    |
#|2     |pig     |cat     |null    |null    |
#+------+--------+--------+--------+--------+