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,您可以使用 whensplitsize 【参考方案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(" ") &lt; 3)。应该是len(x.split(" ")) &lt; 3 您可能想尝试@pault 提供的替代方法。 udf 很灵活,但并不总是那么高效。

以上是关于TypeError:无效参数,不是字符串或列:pyspark UDF的主要内容,如果未能解决你的问题,请参考以下文章

python脚本中的TypeError

TypeError:“错误”是此函数的无效关键字参数

PySpark:TypeError:条件应该是字符串或列

TypeError:int() 参数必须是字符串或数字,而不是 'datetime.datetime'

TypeError:获取参数数组的类型无效 numpy.ndarray,必须是字符串或张量。 (不能将 ndarray 转换为张量或操作。)

获取“first_name”的Django是此函数的无效关键字参数“创建模型类实例时的TypeError”