我的目标是将PySpark.DataFrame列中的所有否定元素替换为零。
输入数据
+------+
| col1 |
+------+
| -2 |
| 1 |
| 3 |
| 0 |
| 2 |
| -7 |
| -14 |
| 3 |
+------+
所需的输出数据
+------+
| col1 |
+------+
| 0 |
| 1 |
| 3 |
| 0 |
| 2 |
| 0 |
| 0 |
| 3 |
+------+
基本上我可以按照以下步骤进行操作:
df = df.withColumn('col1', F.when(F.col('col1') < 0, 0).otherwise(F.col('col1'))
或udf可以定义为
import pyspark.sql.functions as F
smooth = F.udf(lambda x: x if x > 0 else 0, IntegerType())
df = df.withColumn('col1', smooth(F.col('col1')))
或
df = df.withColumn('col1', (F.col('col1') + F.abs('col1')) / 2)
或
df = df.withColumn('col1', F.greatest(F.col('col1'), F.lit(0))
我的问题是,哪种方法最有效? Udf存在优化问题,因此绝对不是正确的方法。但是我不知道如何比较其他两种情况。答案之一应该是绝对地进行实验并比较平均运行时间等。但是我想从理论上比较这些方法(和新方法)。
预先感谢...
答案 0 :(得分:0)
您可以在列if x > 0: x else 0
上简单地写一列。这将是最好的方法。
理论上已经解决了这个问题:Spark functions vs UDF performance?
import pyspark.sql.functions as F
df = df.withColumn("only_positive", F.when(F.col("col1") > 0, F.col("col1")).otherwise(0))
如果将其传递给col1
,则可以在原始数据框中覆盖withColumn()