Python Round 函数在 pyspark 中的问题

8
我是相对较新的Spark用户,在导入pyspark函数后使用Python内置的round()函数时遇到了问题。这似乎与我如何导入pyspark函数有关,但我不确定其中的区别,也不知道为什么一种方式会引起问题而另一种方式不会。
期望的行为:
import pyspark.sql.functions
print(round(3.14159265359,2))
>>> 3.14

意外行为:

from pyspark.sql.functions import *
print(round(3.14159265359,2))
>>> ERROR

AttributeError                            Traceback (most recent call last)
<ipython-input-1-50155ca4fa82> in <module>()
      1 from pyspark.sql.functions import *
----> 2 print(round(3.1454848383,2))

/opt/spark/python/pyspark/sql/functions.py in round(col, scale)
    503     """
    504     sc = SparkContext._active_spark_context
--> 505     return Column(sc._jvm.functions.round(_to_java_column(col), scale))
    506 
    507 

AttributeError: 'NoneType' object has no attribute '_jvm'

2
我认为在使用这个函数之前,你需要初始化一个 SparkContext。错误信息中出现了“NoneType”对象没有属性“_jvm”==>sc 是 NoneType==>SparkContext 不存在。 第一种情况是可行的,因为它仍然使用原生的round函数,如果你想要使用pyspark函数,你需要调用pyspark.sql.functions.round(3.14159265359,2)。 - Tony Pellerin
但问题在于,我不想使用pyspark的round函数。如果我执行“from pyspark.sql.functions import *”,似乎pyspark会重载round()函数...? - Mark Griggs
@MGriggs:“这就好像pyspark正在过载round()函数一样……?” 这正是它所做的。你还指望import *以其他方式工作吗?请阅读“为什么import *不好?”(https://dev59.com/JXE95IYBdhLWcg3wQ7uc)。 - pault
5个回答

8

导入 import pyspark.sql.functions as F 以避免冲突。

这样,您可以正常使用所有Python内置函数,并且当您想要使用pyspark函数时,请使用它们如 F.round


1
我在下面给出了如何使用DataFrame的答案。看到这个答案后,我意识到我误解了问题。将函数导入为F是常见做法。你也可以用__builtin__.round()引用Python的round函数,但那很丑陋。删除我的错误答案。 - Michael West
OP在评论中特别提到他不想使用pyspark函数。确实,这使得代码变得丑陋,也许我认为最好还是遵循常规做法 :) - mayank agrawal

5

2
如果你有一长段代码,其中你已经使用了pyspark.sql.functions却没有像F这样的引用。那么为了仅使用python自带的round功能,在pyspark代码中可以使用__builtins__.round()。@michael_west几乎是正确的,但模块应该是__builtins__而不是__builtin__。 举个例子:
from builtins import round

k = round(123.456)

1
我本来打算修复所有使用 pyspark.sql.functions.round 的代码,以便我可以使用内置的 round 函数,但我忘记了 builtins 模块的存在。在期限紧迫、时间紧张的情况下,导入 builtins 并稍后调用 builtins.round 要容易得多,所以感谢您提供的答案! - hlongmore

0
解决问题请使用以下代码/方法

import pyspark.sql.functions as func

在这里,使用 'func' 告诉编译器使用 pyspark.sql.functions 的 'round' 函数而不是本地函数。
以下是示例用法。

display(df_film.withColumn('HourLength', func.round(df_film['Length']/60,2)))


0

我也遇到了同样的问题,但我不想给pyspark.sql.functions取别名,所以在这里只需给round取别名即可。

from pyspark.sql.functions import round as sqlround

2
这是一个解决方案还是你在说你有类似的问题? - Ruli
@Ruli,这对我来说看起来是一个有效的解决方案。 - mck
@mck 是的,但描述有点混淆,这就是为什么会有问题的原因。 - Ruli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接