<p>使用星型扩展似乎会导致为每个扩展的元素运行一次UDF,如图所示。你知道吗</p>
<pre><code>df.select(new_udf(F.array(cols)).alias('results')).select(F.col('results.*')).explain()
# == Physical Plan ==
# *(1) Project [pythonUDF1#109.id AS id#104, pythonUDF1#109.name AS name#105]
# +- BatchEvalPython [<lambda>(array(id#0, name#1)), <lambda>(array(id#0, name#1))], [id#0, name#1, pythonUDF0#108, pythonUDF1#109]
# +- Scan ExistingRDD[id#0,name#1]
</code></pre>
<p>如果希望保持当前的代码结构,可以通过将其包装在数组中并执行分解来解决问题。你知道吗</p>
<pre><code>df.select(F.explode(F.array(new_udf(F.array(cols)))).alias('results')).select(F.col('results.*')).show(truncate=False)
# + + +
# |id |name |
# + + +
# |123456|Computer x Science x|
# + + +
</code></pre>
<p>根据您的用例,如果您可以用这种方式重新实现UDF,即每行只处理一个特定的列而不是整行,那么代码的可读性会更好。你知道吗</p>
<pre><code>def rep_str(string):
res = string
res = res.replace('Computer', 'Computer x')
res = res.replace('Science', 'Science x')
return res
rep_str_udf = F.udf(lambda s: rep_str(s), StringType())
df.withColumn('new_name', rep_str_udf(df.name)).show()
# + + + +
# | id| name| new_name|
# + + + +
# |123456|Computer Science|Computer x Science x|
# + + + +
</code></pre>