Skip to main content
 首页 » 编程设计

python之PySpark:调用 o51.showString 时出错。没有名为 XXX 的模块

2024年08月16日36lidabo

我的pyspark版本是2.2.0。我遇到了一个奇怪的问题。我尝试将其简化如下。文件结构:

|root 
|-- cast_to_float.py 
|-- tests 
    |-- test.py 

在 cast_to_float.py 中,我的代码:

from pyspark.sql.types import FloatType 
from pyspark.sql.functions import udf 
 
def cast_to_float(y, column_name): 
    return y.withColumn(column_name, y[column_name].cast(FloatType())) 
 
def cast_to_float_1(y, column_name): 
    to_float = udf(cast2float1, FloatType()) 
    return y.withColumn(column_name, to_float(column_name)) 
 
def cast2float1(a): 
    return 1.0 

在test.py中:

from pyspark.sql import SparkSession 
import os 
import sys 
parentPath = os.path.abspath('..') 
if parentPath not in sys.path: 
    sys.path.insert(0, parentPath) 
 
from cast_to_float import * 
spark = SparkSession.builder.appName("tests").getOrCreate() 
df = spark.createDataFrame([ 
            (1, 1), 
            (2, 2), 
            (3, 3), 
        ], ["ID", "VALUE"]) 
df1 = cast_to_float(df, 'ID') 
df2 = cast_to_float_1(df, 'ID') 
 
df1.show() 
df1.printSchema() 
df2.printSchema() 
df2.show() 

然后我在测试文件夹中运行测试,我收到来自最后一行的错误消息,说:

+---+-----+ 
| ID|VALUE| 
+---+-----+ 
|1.0|    1| 
|2.0|    2| 
|3.0|    3| 
+---+-----+ 
 
root 
 |-- ID: float (nullable = true) 
 |-- VALUE: long (nullable = true) 
 
root 
 |-- ID: float (nullable = true) 
 |-- VALUE: long (nullable = true) 
 
    Py4JJavaError                             Traceback (most recent call last) 
<ipython-input-4-86eb5df2f917> in <module>() 
     19 df1.printSchema() 
     20 df2.printSchema() 
---> 21 df2.show() 
... 
Py4JJavaError: An error occurred while calling o257.showString. 
... 
ModuleNotFoundError: No module named 'cast_to_float' 
... 

看来 cast_to_float 是导入的,否则,我什至无法获得 df1。

如果我把test.py和cast_to_float.py放在同一个目录下,然后在那个目录下运行,就OK了。有任何想法吗?谢谢!


我使用了@user8371915 __file__ 方法,发现在root 文件夹中运行它是可以的。

请您参考如下方法:

就目前而言,结果将取决于您调用脚本的工作目录。

如果你在 root 中,这将添加它的父级。您应该使用相对于 __file__ 的路径(参见 what does the __file__ variable mean/do? ):

parentPath = os.path.join( 
    os.path.abspath(os.path.dirname(__file__)),  
    os.path.pardir 
) 

但我会建议使用适当的包结构。

注意:

这仅涵盖本地模式和驱动程序路径,即使在本地模式下,worker 路径也不受驱动程序路径的影响。

要处理执行程序路径(更改后您会得到执行程序异常),您仍应将模块分发给工作人员 How to use custom classes with Apache Spark (pyspark)? .

spark = SparkSession.builder.appName("tests").getOrCreate() 
spark.sparkContext.addPyFile("/path/to/cast_to_float.py")