TypeError:无效参数,不是字符串或列:pyspark UDF
Posted
技术标签:
【中文标题】TypeError:无效参数,不是字符串或列:pyspark UDF【英文标题】:TypeError: Invalid argument, not a string or column: pyspark UDFs 【发布时间】:2018-10-15 18:43:41 【问题描述】:我正在一个类中创建一个火花 UDF。当我执行下面的代码时,我得到了异常。
class A(B):
def __init__(self,spark):
B.__init__(self)
self.spark = spark
def process(self, df):
df = df.withColumn("col_sub_entry", self.conditions_title("entry_title"))
def conditions_entry_title(self,x:StringType()):
if len(x.split(" ") < 3):
return 0
else :
return x
conditions_title = udf(conditions_entry_title, IntegerType())
【问题讨论】:
能贴出整个类的实现吗?至少 udf 是如何实现的?我不认为您在此处定义udf
的方式是类中的有效语法。
我做过,检查一次
当我在课外使用 UDF 时它对我有用。
是的,您必须记住 pyspark 工作节点没有在驱动程序上创建类实例。他们那里只有基本的python方法。
我只是想指出,您不需要 udf
,您可以使用 when
、split
和 size
。
【参考方案1】:
当可以使用 API 函数完成相同的操作时,您应该始终 avoid using udfs。
我会这样做:
from pyspark.sql.functions import when, col, size, split
class A:
def __init__(self, spark):
# B.__init__(self)
self.spark = spark
def process(self, df):
df = df.withColumn("col_sub_entry", A.conditions_title("entry_title"))
return df
@staticmethod
def conditions_title(someColumn):
return when(size(split(col(someColumn), "\s")) < 3, 0).otherwise(1)
甚至:
@staticmethod
def conditions_title(someColumn):
return (size(split(col(someColumn), "\s")) >= 3).cast("int")
【讨论】:
我们可以在什么时候执行“in”条件?例如“字符串类型”中的“字符串” 是的,您可以使用isin
,例如:when(col(someColumn).isin(someIterable), valueIfTrue).otherwise(valueIfFalse)
。您还可以进行正则表达式匹配。这取决于你想做什么。
当我使用你的拆分方法时。它解决了这个错误:IndexError: 只有整数、切片 (:
)、省略号 (...
)、numpy.newaxis (None
) 和整数或布尔数组是有效的索引
@LUZO 该错误消息似乎与您提供的任何代码无关。没有minimal reproducible example 很难调试,但我认为最好提出一个新问题。【参考方案2】:
你在你的udf中定义的conditions_title
不一致;您似乎正在尝试将其定义为类的静态成员,但通过self
将其称为实例方法,并且由于此处未使用udf 中的self
,您可以将其定义为静态方法:
from pyspark.sql.functions import udf
from pyspark.sql.types import IntegerType, StringType
class A:
def __init__(self, spark):
# B.__init__(self)
self.spark = spark
def process(self, df):
df = df.withColumn("col_sub_entry", A.conditions_title("entry_title"))
return df
@staticmethod
@udf(IntegerType())
def conditions_title(x: StringType):
if len(x.split(" ")) < 3:
return 0
else :
return 1
【讨论】:
我们可以定义 x:StringType() 吗?我收到错误,语法无效。 @Prazy 它适用于我在不带括号的情况下定义x: StringType
。
它给我这个错误 TypeError: '
在您的代码中检查len(x.split(" ") < 3)
。应该是len(x.split(" ")) < 3
您可能想尝试@pault 提供的替代方法。 udf
很灵活,但并不总是那么高效。以上是关于TypeError:无效参数,不是字符串或列:pyspark UDF的主要内容,如果未能解决你的问题,请参考以下文章
TypeError:int() 参数必须是字符串或数字,而不是 'datetime.datetime'
TypeError:获取参数数组的类型无效 numpy.ndarray,必须是字符串或张量。 (不能将 ndarray 转换为张量或操作。)