Групповое регулярное выражение Spark Scala - PullRequest
0 голосов
/ 21 мая 2019

Предположим, у меня есть кадр данных, который выглядит следующим образом:

val df2 = Seq({"A:job_1, B:whatever1"}, {"A:job_1, B:whatever2"} , {"A:job_2, B:whatever3"}).toDF("values")
df2.show()

Как я могу сгруппировать его по регулярному выражению, например, "job_", а затем взять первый элемент, заканчивающийся чем-то вроде:

|A:job_1, B:whatever1|
|A:job_2, B:whatever3|

Большое спасибо и всего наилучшего

Ответы [ 2 ]

2 голосов
/ 21 мая 2019

Вероятно, вам следует просто создать новый столбец с regexp_extract и удалить этот столбец!

import org.apache.spark.sql.{functions => F}

df2.
    withColumn("A", F.regexp_extract($"values", "job_[0-9]+", 0)). // Extract the key of the groupBy
    groupBy("A").
    agg(F.first("values").as("first value")). // Get the first value
    drop("A").
    show()

Вот катализатор, если вы хотите пойти дальше в понимании!

Как вы можете видеть в оптимизированном логическом плане, два следующих пункта строго эквивалентны:

  • явно создавая новый столбец с: .withColumn("A", F.regexp_extract($"values", "job_[0-9]+", 0))
  • группировка по новому столбцу с: .groupBy(F.regexp_extract($"values", "job_[0-9]+", 0).alias("A"))

Вот план катализатора:

== Parsed Logical Plan ==
'Aggregate [A#198], [A#198, first('values, false) AS first value#206]
+- Project [values#3, regexp_extract(values#3, job_[0-9]+, 0) AS A#198]
   +- Project [value#1 AS values#3]
      +- LocalRelation [value#1]

== Analyzed Logical Plan ==
A: string, first value: string
Aggregate [A#198], [A#198, first(values#3, false) AS first value#206]
+- Project [values#3, regexp_extract(values#3, job_[0-9]+, 0) AS A#198]
   +- Project [value#1 AS values#3]
      +- LocalRelation [value#1]

== Optimized Logical Plan ==
Aggregate [A#198], [A#198, first(values#3, false) AS first value#206]
+- LocalRelation [values#3, A#198]
1 голос
/ 21 мая 2019

Преобразуйте ваши данные в Seq с двумя столбцами и управляйте им:

val aux = Seq({"A:job_1, B:whatever1"}, {"A:job_1, B:whatever2"} , {"A:job_2, B:whatever3"})
  .map(x=>(x.split(",")(0).replace("A:","")
    ,x.split(",")(1).replace("B:","")))
  .toDF("A","B")
  .groupBy("A")

Я удалил A: и B:, но это не обязательно.

Или вы можетепопробуй:

df2.withColumn("A",col("value").substr(4,8))
  .groupBy("A")
...