Pyspark 如何使用withColumn向UDF传递额外参数

Pyspark 如何使用withColumn向UDF传递额外参数,pyspark,user-defined-functions,Pyspark,User Defined Functions,如何使用withColumn向UDF传递额外参数 df = spark.createDataFrame([ ["aaa","1"], ["bbb","2"], ["ccc","5"] ]).toDF("text","id") def title(x,y): if y: x = x.title() re

如何使用withColumn向UDF传递额外参数

df = spark.createDataFrame([
  ["aaa","1"],
  ["bbb","2"],
  ["ccc","5"]
]).toDF("text","id")

def title(x,y):
   if y:
      x = x.title()
   return x

title_udf = udf(lambda x: title(x,y), StringType())
spark.udf.register('title_udf', title_udf)

df = df.withColumn('text_title',title_udf('text',True)

当我尝试这样做时,我得到一个错误:参数无效,不是字符串或列。…

udf s只能识别行元素。所以要传递固定参数,必须使用lit函数。此外,还必须更正您的自定义项定义。试试这个:

import pyspark.sql.functions as F
from pyspark.sql.types import *
df = spark.createDataFrame([
  ["aaa","1"],
  ["bbb","2"],
  ["ccc","5"]
]).toDF("text","id")

def title(x,y):
   if y:
      x = x.title()
   return x

title_udf = F.udf(title, StringType())

df = df.withColumn('text_title',title_udf('text',F.lit(True)))

 df.show()
+----+---+----------+
|text| id|text_title|
+----+---+----------+
| aaa|  1|       Aaa|
| bbb|  2|       Bbb|
| ccc|  5|       Ccc|
+----+---+----------+
正如@powers在注释中所指出的,如果此输出是您的最终目的,那么您可以使用initcap函数在不使用udf的情况下执行此操作

df = df.withColumn("text_title",F.when(F.lit(True),F.initcap(F.col('text'))).otherwise(F.col('text')))
您还可以使用其他列作为条件,如“id”列

df = df.withColumn("text_title",F.when(F.col('id')>2,F.initcap(F.col('text'))).otherwise(F.col('text')))

自定义项只能识别行元素。所以要传递固定参数,必须使用lit函数。此外,还必须更正您的自定义项定义。试试这个:

import pyspark.sql.functions as F
from pyspark.sql.types import *
df = spark.createDataFrame([
  ["aaa","1"],
  ["bbb","2"],
  ["ccc","5"]
]).toDF("text","id")

def title(x,y):
   if y:
      x = x.title()
   return x

title_udf = F.udf(title, StringType())

df = df.withColumn('text_title',title_udf('text',F.lit(True)))

 df.show()
+----+---+----------+
|text| id|text_title|
+----+---+----------+
| aaa|  1|       Aaa|
| bbb|  2|       Bbb|
| ccc|  5|       Ccc|
+----+---+----------+
正如@powers在注释中所指出的,如果此输出是您的最终目的,那么您可以使用initcap函数在不使用udf的情况下执行此操作

df = df.withColumn("text_title",F.when(F.lit(True),F.initcap(F.col('text'))).otherwise(F.col('text')))
您还可以使用其他列作为条件,如“id”列

df = df.withColumn("text_title",F.when(F.col('id')>2,F.initcap(F.col('text'))).otherwise(F.col('text')))
使用initcap内置函数可以避免udf

例如:

使用initcap内置函数可以避免udf

例如:


@Raghu-很好的答案+1。作为额外的学分分配,您可能还想解释如何在不使用自定义项的情况下解决此问题。尽可能避免使用UDF,我认为这个问题可以用Spark本机函数来解决。@Powers-谢谢你的提示。。我总是假设给定的数据是一个玩具示例:-@Raghu-很好的答案+1。作为额外的学分分配,您可能还想解释如何在不使用自定义项的情况下解决此问题。尽可能避免使用UDF,我认为这个问题可以用Spark本机函数来解决。@Powers-谢谢你的提示。。我总是假设给定的数据是一个玩具示例:-谢谢。我知道这是不是真的,但这只是UDFThanks的一个例子。我知道这是否正确,但这只是UDF的一个例子