在Spark 2.4上的pyspark.sql.functions.max()。over(window)上使用.where()会引发Java异常

时间:2019-02-03 23:24:44

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

我在StackOverflow上发表了一篇关于返回由另一列分组的列的最大值的帖子,并得到了意外的Java异常。

以下是测试数据:

import pyspark.sql.functions as f
data = [('a', 5), ('a', 8), ('a', 7), ('b', 1), ('b', 3)]
df = spark.createDataFrame(data, ["A", "B"])
df.show()

+---+---+
|  A|  B|
+---+---+
|  a|  5|
|  a|  8|
|  a|  7|
|  b|  1|
|  b|  3|
+---+---+

以下是据称可用于其他用户的解决方案:

from pyspark.sql import Window
w = Window.partitionBy('A')
df.withColumn('maxB', f.max('B').over(w))\
    .where(f.col('B') == f.col('maxB'))\
    .drop('maxB').show()

应产生以下输出:

#+---+---+
#|  A|  B|
#+---+---+
#|  a|  8|
#|  b|  3|
#+---+---+

相反,我得到:

java.lang.UnsupportedOperationException: Cannot evaluate expression: max(input[2, bigint, false]) windowspecdefinition(input[0, string, true], specifiedwindowframe(RowFrame, unboundedpreceding$(), unboundedfollowing$()))

我只在Databricks的Spark 2.4上尝试过此操作。我尝试了等效的SQL语法,并得到了相同的错误。

1 个答案:

答案 0 :(得分:2)

Databricks支持能够在Spark 2.4上重现该问题,但在较早的版本中却没有。显然,这是由于制定物理计划的方式不同(如果需要,我可以发布其答复)。已计划修复。

同时,这是对原始问题的一种替代解决方案,该问题不会成为版本2.4的牺牲品:

df.withColumn("maxB", f.max('B').over(w)).drop('B').distinct().show()

+---+----+
|  A|maxB|
+---+----+
|  b|   3|
|  a|   8|
+---+----+