优化Spark数据框操作

时间:2020-05-17 06:07:46

标签: apache-spark apache-spark-sql

我有该模式的spark(2.4版)数据框。

+----------+
| ColumnA  |
+----------+
| 1000@Cat |
| 1001@Dog |
| 1000@Cat |
| 1001@Dog |
| 1001@Dog |
+----------+

我有条件地使用以下代码对附加到字符串的数字进行正则表达式删除

dataset.withColumn("ColumnA",when(regexp_extract(dataset.col("ColumnA"), "\\@(.*)", 1)
                                                    .equalTo(""), dataset.col("ColumnA"))
                                               .otherwise(regexp_extract(dataset.col("ColumnA"), "\\@(.*)", 1)));

这将导致以下格式的数据帧

+---------+
| ColumnA |
+---------+
| Cat     |
| Dog     |
| Cat     |
| Dog     |
| Dog     |
+---------+

这可以正确运行并产生所需的输出。

但是两次执行regexp_extract操作,一次检查返回的字符串是否为空,如果不是,则在列上重新应用regexp_extract。

此代码是否可以进行优化以使其性能更好?

1 个答案:

答案 0 :(得分:1)

使用split函数代替regexp_extract

请检查以下代码以及执行时间

scala> df.show(false)
+--------+
|columna |
+--------+
|1000@Cat|
|1001@Dog|
|1000@Cat|
|1001@Dog|
|1001@Dog|
+--------+


scala> spark.time(df.withColumn("parsed",split($"columna","@")(1)).show(false))
+--------+------+
|columna |parsed|
+--------+------+
|1000@Cat|Cat   |
|1001@Dog|Dog   |
|1000@Cat|Cat   |
|1001@Dog|Dog   |
|1001@Dog|Dog   |
+--------+------+

Time taken: 14 ms

scala> spark.time { df.withColumn("ColumnA",when(regexp_extract($"columna", "\\@(.*)", 1).equalTo(""), $"columna").otherwise(regexp_extract($"columna", "\\@(.*)", 1))).show(false) }
+-------+
|ColumnA|
+-------+
|Cat    |
|Dog    |
|Cat    |
|Dog    |
|Dog    |
+-------+

Time taken: 22 ms

scala>

contains函数可检查列中的@

scala> spark.time(df.withColumn("parsed",when($"columna".contains("@"), lit(split($"columna","@")(1))).otherwise("")).show(false))
+--------+------+
|columna |parsed|
+--------+------+
|1000@Cat|Cat   |
|1001@Dog|Dog   |
|1000@Cat|Cat   |
|1001@Dog|Dog   |
|1001@Dog|Dog   |
+--------+------+

Time taken: 14 ms

相关问题