【问题标题】:With PySpark how do I populate values in a column based on either groupby/window/partition and perform a UDF?使用 PySpark 如何根据 groupby/window/partition 填充列中的值并执行 UDF?
【发布时间】:2019-10-22 12:42:44
【问题描述】:

我正在尝试填充列中的缺失值。组/分区中第一行或以下任何行(根据日期按顺序排列)中的配置文件列将具有必须填充到配置文件列的以下单元格中的值。

我尝试使用窗口函数运行它,但无法将 UDF 应用于窗口函数。

valuesA = [('1',"", "20190108"),('1',"", "20190107"),('1',"abcd", "20190106"),('1',"", "20190105"),('1',"", "20190104"),('2',"wxyz", "20190103"),('2',"", "20190102"),('2',"", "20190101")]
TableA = spark.createDataFrame(valuesA,['vid','profile', 'date'])

valuesB = [('1',"null", "20190108"),('1',"null", "20190107"),('1',"abcd", "20190106"),('1',"abcd", "20190105"),('1',"abcd", "20190104"),('2',"wxyz", "20190103"),('2', "wxyz", "20190102"),('2', "wxyz", "20190101")]
TableB = spark.createDataFrame(valuesB,['vid','profile', 'date'])

TableA.show()
TableB.show()
Table A: This is what I have. 
+---+-------+--------+
|vid|profile|    date|
+---+-------+--------+
|  1|       |20190108|
|  1|       |20190107|
|  1|   abcd|20190106|
|  1|       |20190105|
|  1|       |20190104|
|  2|   wxyz|20190103|
|  2|       |20190102|
|  2|       |20190101|
+---+-------+--------+

Table B: What I am expecting. 
+---+-------+--------+
|vid|profile|    date|
+---+-------+--------+
|  1|   null|20190108|
|  1|   null|20190107|
|  1|   abcd|20190106|
|  1|   abcd|20190105|
|  1|   abcd|20190104|
|  2|   wxyz|20190103|
|  2|   wxyz|20190102|
|  2|   wxyz|20190101|
+---+-------+--------+

【问题讨论】:

    标签: pyspark window user-defined-functions populate partition


    【解决方案1】:

    您可以使用last 窗口函数。 注意 - 首先withColumn 是用空值替换所有空字符串 - last 函数默认跳过空值,这在本例中是我们想要的。

    from pyspark.sql.window import Window
    from pyspark.sql.functions import *
    TableB = TableA.withColumn('profile', when(length('profile') == 0, lit(None)).otherwise(col('profile')))\
        .withColumn("profile", last(col('profile'), True).over(Window.partitionBy('vid').orderBy(col('date').desc())))
    
    TableB.show()
    

    输出:

    +---+-------+--------+
    |vid|profile|    date|
    +---+-------+--------+
    |  1|   null|20190108|
    |  1|   null|20190107|
    |  1|   abcd|20190106|
    |  1|   abcd|20190105|
    |  1|   abcd|20190104|
    |  2|   wxyz|20190103|
    |  2|   wxyz|20190102|
    |  2|   wxyz|20190101|
    +---+-------+--------+
    

    【讨论】:

    • 非常感谢,效果很好。 last 方法中的 ignorenulls 参数是一个不错的选择。这就是我所缺少的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2023-01-11
    • 2018-03-02
    • 2021-11-12
    • 2021-04-25
    • 2019-06-06
    相关资源
    最近更新 更多