补充一下已经得到认可的答案:现在可以做类似于OP尝试做的事情,即使用**
运算符,甚至使用Python内置的pow
函数:
from pyspark.sql import SparkSession
from pyspark.sql.functions import pow as pow_
spark = SparkSession.builder.getOrCreate()
df = spark.createDataFrame([(1, ), (2, ), (3, ), (4, ), (5, ), (6, )], 'n: int')
df = df.withColumn('pyspark_pow', pow_(df['n'], df['n'])) \
.withColumn('python_pow', pow(df['n'], df['n'])) \
.withColumn('double_star_operator', df['n'] ** df['n'])
df.show()
+---+-----------+----------+--------------------+
| n|pyspark_pow|python_pow|double_star_operator|
+---+-----------+----------+--------------------+
| 1| 1.0| 1.0| 1.0|
| 2| 4.0| 4.0| 4.0|
| 3| 27.0| 27.0| 27.0|
| 4| 256.0| 256.0| 256.0|
| 5| 3125.0| 3125.0| 3125.0|
| 6| 46656.0| 46656.0| 46656.0|
+---+-----------+----------+--------------------+
可以看到,PySpark和Python的pow
函数以及**
运算符返回的结果相同。即使其中一个参数是标量值也能正常工作:
df = df.withColumn('pyspark_pow', pow_(2, df['n'])) \
.withColumn('python_pow', pow(2, df['n'])) \
.withColumn('double_star_operator', 2 ** df['n'])
df.show()
+---+-----------+----------+--------------------+
| n|pyspark_pow|python_pow|double_star_operator|
+---+-----------+----------+--------------------+
| 1| 2.0| 2.0| 2.0|
| 2| 4.0| 4.0| 4.0|
| 3| 8.0| 8.0| 8.0|
| 4| 16.0| 16.0| 16.0|
| 5| 32.0| 32.0| 32.0|
| 6| 64.0| 64.0| 64.0|
+---+-----------+----------+--------------------+
我认为Python的
pow
现在能够在PySpark列上工作的原因是,当只使用两个参数时,
pow
等同于
**
运算符(请参见文档
here),而
**
运算符会使用对象自己的幂运算实现,如果该对象被操作时定义了幂运算实现(请参见此SO响应
here)。
显然,PySpark的
Column
具有
__pow__
运算符的适当定义(请参见
Column
的
source code)。
我不确定为什么最初
**
运算符不起作用,但我认为这与
Column
最初的定义方式有关。
测试使用的堆栈是Python 3.8.5和PySpark 3.1.1,但我也看到了这种行为适用于PySpark >= 2.4。