从pyspark中的下一列中删除空值和移位值

从pyspark中的下一列中删除空值和移位值,pyspark,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 我的目标是:

我需要将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上得到):


然后我重命名这些列。但我不知道如何在Pyspark上实现这一点。

这里有一种在Spark 2.4+版上实现这一点的方法:

创建所需列的数组并按条件排序,条件如下:

  • 首先对非空值排序
  • 按值在列中的显示顺序对值进行排序
  • 我们可以用计算机进行排序。要实现多个条件,请使用。为了便于提取所需的值(即本例中的动物),还可以提取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个索引中的项

    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    |
    #+------+--------+--------+--------+--------+
    
    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    |
    #+------+--------+--------+--------+--------+