Python 自连接后使用UDF的Spark 2.0过滤器

Python 自连接后使用UDF的Spark 2.0过滤器,python,apache-spark,pyspark,spark-dataframe,Python,Apache Spark,Pyspark,Spark Dataframe,我需要使用自己的用户定义函数过滤Spark数据帧。我的数据帧是使用jdbc连接从数据库读取的,然后在spark中进行自连接操作,然后再进行过滤。尝试收集过滤器后的数据帧时出错 我已经在spark 1.6中成功地使用了它。但是,在昨天升级到2.0之后,它失败了,错误如下: py4j.protocol.Py4JJavaError: An error occurred while calling o400.collectToPython. : java.lang.UnsupportedOperatio

我需要使用自己的用户定义函数过滤Spark数据帧。我的数据帧是使用jdbc连接从数据库读取的,然后在spark中进行自连接操作,然后再进行过滤。尝试
收集过滤器后的数据帧时出错

我已经在spark 1.6中成功地使用了它。但是,在昨天升级到2.0之后,它失败了,错误如下:

py4j.protocol.Py4JJavaError: An error occurred while calling o400.collectToPython.
: java.lang.UnsupportedOperationException: Cannot evaluate expression: 
<lambda>(input[0, string, true])

在这种情况下我做错了什么吗?这是2的bug还是应该考虑两个版本之间的行为变化?

这是PyScPix.

中的一个bug。 我已经在这里注册了一个bug

这个问题出现在左外联接、右外联接和外联接中,但不出现在内联接中

一种解决方法是在筛选之前缓存联接结果

例如:

result=df1.join(df2,col('df1.id')==col('df2.manager\u id'),
'left_outer')。选择(df2.name).cache()

我的头撞到了墙上,因为在上一个会话中有效的udf失败了。这救了我!谢谢蒂姆!
from pyspark.sql.functions import udf, col
from pyspark.sql.types import BooleanType

spark = SparkSession.builder.master('local').appName('test').getOrCreate()

# this works successfully
df = spark.createDataFrame([('Alice', 1), ('Bob', 2), ('Dan', None)], 
                           ['name', 'age'])
df.filter(udf(lambda x: 'i' in x, BooleanType())(df.name)).collect()
>>> [Row(name=u'Alice', age=1)]

# this produces the error
df_emp = spark.createDataFrame([(1, 'Alice', None), (2, 'Bob', 1), 
                                (3, 'Dan', 2), (4, 'Joe', 2)], 
                               ['id', 'name', 'manager_id'])
df1 = df_emp.alias('df1')
df2 = df_emp.alias('df2')
cols = df1.columns
# the self-join
result = df1.join(df2, col('df1.id') == col('df2.manager_id'), 'left_outer')
result.collect()
>>> [Row(id=1, name=u'Alice', manager_id=None), 
     Row(id=3, name=u'Dan', manager_id=2), Row(id=2, name=u'Bob', manager_id=1), 
     Row(id=2, name=u'Bob', manager_id=1), Row(id=4, name=u'Joe', manager_id=2)]

# simple udf filter
filtered = result.filter(udf(lambda x: 'i' in x, BooleanType())(result.name))
filtered.collect()
# the above error is produced...