假设你有一个文件,我们称之为
如果我们在与两个函数定义的文件(
一切运行良好。然而,我的目标是将逻辑漂亮地分离在多个函数中,我也可以单独测试这些函数。我认为可以通过使用“spark.sparkContext.addPyFile('...udfs.py')”将“udfs.py”文件(或整个压缩的文件夹)提交给执行程序来解决此问题。但是:
1. 我觉得这有点冗长(特别是如果您需要压缩文件夹等...) 2. 这并不总是容易/可能(例如,“udfs.py”可能正在使用许多其他模块,这些模块随后也需要被提交,导致一定程度的连锁反应...) 3. 使用“addPyFile”存在一些其他不便之处(例如{{link1:autoreload可能停止工作}}等)
因此,问题是:是否有一种方法可以同时完成所有这些操作?
udfs.py
,其中包含以下内容:def nested_f(x):
return x + 1
def main_f(x):
return nested_f(x) + 1
然后您想将 main_f
函数制作成一个用户自定义函数,并在数据框上运行它:
import pyspark.sql.functions as fn
import pandas as pd
pdf = pd.DataFrame([[1], [2], [3]], columns=['x'])
df = spark.createDataFrame(pdf)
_udf = fn.udf(main_f, 'int')
df.withColumn('x1', _udf(df['x'])).show()
如果我们在与两个函数定义的文件(
udfs.py
)相同的文件中执行此操作,则可以正常工作。但是,尝试从不同的文件(例如main.py
)执行此操作会产生错误ModuleNotFoundError: No module named ...
:...
import udfs
_udf = fn.udf(udfs.main_f, 'int')
df.withColumn('x1', _udf(df['x'])).show()
我注意到如果我将nested_f
实际嵌套在main_f
中,就像这样:
def main_f(x):
def nested_f(x):
return x + 1
return nested_f(x) + 1
一切运行良好。然而,我的目标是将逻辑漂亮地分离在多个函数中,我也可以单独测试这些函数。我认为可以通过使用“spark.sparkContext.addPyFile('...udfs.py')”将“udfs.py”文件(或整个压缩的文件夹)提交给执行程序来解决此问题。但是:
1. 我觉得这有点冗长(特别是如果您需要压缩文件夹等...) 2. 这并不总是容易/可能(例如,“udfs.py”可能正在使用许多其他模块,这些模块随后也需要被提交,导致一定程度的连锁反应...) 3. 使用“addPyFile”存在一些其他不便之处(例如{{link1:autoreload可能停止工作}}等)
因此,问题是:是否有一种方法可以同时完成所有这些操作?
- 将UDF的逻辑分成几个Python函数
- 从定义逻辑的文件中使用UDF
- 不需要使用
addPyFile
提交任何依赖项
额外加分项是解释为什么这样做可以/为什么不能这样做!