如果存在于DataFrame的字符串列中,则删除后缀

时间:2017-11-22 00:18:55

标签: apache-spark dataframe

我正在使用Spark 2.2。我想知道在DataFrame

列上删除后缀的性能方面最佳选择是什么

使用udf

val removeSuffix = udf { (id: String) =>
    if (id != null && id.endsWith("XXX")) {
      id.dropRight(3)
    } else {
      id
    }
  }
df.withColumn("c", udf("col"))

或使用regexp内置功能

df.withColumn("c", regexp_replace($"col", "XXX$", ""))

我知道 udf 的速度很慢但是评估每一行的正则表达式会更快吗?

[2018-01-21更新基于用户的回答8983815]

我写了一个基准测试,结果有点令人惊讶

[info] Benchmark                                      Mode  Cnt    Score   Error  Units
[info] RemoveSuffixBenchmark.builtin_optimized        avgt   10  103,188 ± 3,526  ms/op
[info] RemoveSuffixBenchmark.builtin_regexp_replace_  avgt   10   99,173 ± 7,313  ms/op
[info] RemoveSuffixBenchmark.udf                      avgt   10   94,570 ± 5,707  ms/op

对于有兴趣的人,代码在这里:https://github.com/YannMoisan/spark-jmh

1 个答案:

答案 0 :(得分:2)

我怀疑regexp_replace会导致严重的性能问题,但如果您真的担心

import org.apache.spark.sql.functions._ 
import org.apache.spark.sql.Column

def removeSuffix(c: Column) = when(c.endsWith("XXX"), c.substr(lit(0), length(c) - 3)).otherwise(c)

用作:

scala> Seq("fooXXX", "bar").toDF("s").select(removeSuffix($"s").alias("s")).show
+---+
|  s|
+---+
|foo|
|bar|
+---+