PySpark UDF升级后报AttributeError: 'NoneType'无'_jvm'属性问题
解决PySpark UDF升级后出现的AttributeError: 'NoneType' object has no attribute '_jvm'问题
我之前在升级PySpark版本时也碰到过一模一样的错误,咱们来拆解下问题根源和解决办法:
问题原因
你给UDF加了@staticmethod装饰器,这在PySpark 2.x版本(比如你升级后的EMR对应的PySpark2.3)里是不兼容的。PySpark的UDF装饰器@F.udf需要依赖SparkContext的_jvm对象来完成Python和Java端的交互,而静态方法属于类层面,无法获取到所需的Spark上下文实例,导致初始化UDF时找不到_jvm,就抛出了NoneType的错误。之前Python2.7+旧版PySpark能运行,是因为当时的UDF机制对上下文检查没那么严格。
解决方案
方案1:直接移除@staticmethod装饰器
这是最直接的办法,PySpark UDF本身不需要用静态方法修饰,改成普通函数即可:
from pyspark.sql import functions as F @F.udf("array<int>") def create_users_array(val): """接收整数列,返回包含该整数的数组列""" return [val for _ in range(val)] # 调用方式保持不变 df.withColumn("myArray", create_users_array(df["myNumber"]))
方案2:如果需要保留类结构(比如函数在类中)
如果这个UDF是类的一部分,不想改成全局函数,可以把它改成实例方法,或者直接把UDF定义移到类外部。另外,你的UDF逻辑比较简单,也可以用lambda表达式简化写法:
df.withColumn("myArray", F.udf(lambda val: [val] * val, "array<int>")(df["myNumber"]))
这样修改后,UDF就能正常和Spark上下文交互,不会再出现_jvm相关的错误了。
内容的提问来源于stack exchange,提问作者morrime
相关产品推荐
相关产品推荐

