PySpark-如何将pyspark.sql.functions.lag的默认值设置为当前行内的值?

时间:2018-09-20 19:21:40

标签: apache-spark pyspark apache-spark-sql

如何将pyspark.sql.functions.lag的默认值设置为当前行中的值?

例如,给定:

testInput = [(1, 'a'),(2, 'c'),(3, 'e'),(1, 'a'),(1, 'b'),(1, 'b')]
columns = ['Col A', 'Col B']
df = sc.parallelize(testInput).toDF(columns)
df.show()

windowSpecification = Window.partitionBy(col('Col A')).orderBy(col('Col B'))
changedRows = col('Col B') != F.lag(col('Col B'), 1).over(windowSpecification)

df.select(col('Col A'), col('Col B'), changedRows.alias('New Col C')).show()

输出:

+-----+-----+
|Col A|Col B|
+-----+-----+
|    1|    a|
|    2|    c|
|    3|    e|
|    1|    a|
|    1|    b|
|    1|    b|
+-----+-----+

+-----+-----+---------+
|Col A|Col B|New Col C|
+-----+-----+---------+
|    1|    a|     null|
|    1|    a|    false|
|    1|    b|     true|
|    1|    b|    false|
|    3|    e|     null|
|    2|    c|     null|
+-----+-----+---------+

我希望输出看起来像这样:

+-----+-----+---------+
|Col A|Col B|New Col C|
+-----+-----+---------+
|    1|    a|    false|
|    1|    a|    false|
|    1|    b|     true|
|    1|    b|    false|
|    3|    e|    false|
|    2|    c|    false|
+-----+-----+---------+

我当前的解决方法是向lag添加第二个changedRows调用,如下所示:

changedRows = (col('Col B') != F.lag(col('Col B'), 1).over(windowSpecification)) & F.lag(col('Col B'), 1).over(windowSpecification).isNotNull()

但这对我来说并不干净。

我想做类似的事情

changedRows = col('Col B') != F.lag(col('Col B'), 1, col('Col B')).over(windowSpecification)

但是出现错误TypeError: 'Column' object is not callable

1 个答案:

答案 0 :(得分:2)

如果使用pyspark.sql.functions.expr,则可以使用column values as parameters。根据您的情况,对changedRows进行以下修改:

changedRows = F.expr(
    "`Col B` != lag(`Col B`, 1, `Col B`) over (PARTITION BY `Col A` ORDER BY `Col B`)"
)
df.select('Col A', 'Col B', changedRows.alias('New Col C')).show()
#+-----+-----+---------+
#|Col A|Col B|New Col C|
#+-----+-----+---------+
#|    1|    a|    false|
#|    1|    a|    false|
#|    1|    b|     true|
#|    1|    b|    false|
#|    3|    e|    false|
#|    2|    c|    false|
#+-----+-----+---------+

由于空间原因,您必须在反斜杠中引用列名称。