Последовательные динамические фильтры в одном столбце данных Spark в Scala Spark - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть столбец с именем root, и мне нужно отфильтровать фрейм данных на основе различных значений корневого столбца.

Предположим, у меня есть значения в корне: parent, child или sub-child, и я хочу применитьэти фильтры динамически проходят через переменную.

val x = ("parent,child,sub-child").split(",")
x.map(eachvalue <- {

   var df1 = df.filter(col("root").contains(eachvalue))

}

Но когда я делаю это, вместо этого всегда перезаписывается DF1, я хочу применить все 3 фильтра и получить результат.

Майв будущем я могу расширить список до любого количества значений фильтра, и код должен работать.

Спасибо, Баб

Ответы [ 4 ]

0 голосов
/ 21 декабря 2018

Еще один способ использования array_contains и замены аргументов.

scala> val x = ("parent,child,sub-child").split(",")
x: Array[String] = Array(parent, child, sub-child)

scala> val df = Seq(("parent"),("grand-parent"),("child"),("sub-child"),("cousin")).toDF("root")
df: org.apache.spark.sql.DataFrame = [root: string]

scala> df.show
+------------+
|        root|
+------------+
|      parent|
|grand-parent|
|       child|
|   sub-child|
|      cousin|
+------------+


scala> df.withColumn("check", array_contains(lit(x),'root)).show
+------------+-----+
|        root|check|
+------------+-----+
|      parent| true|
|grand-parent|false|
|       child| true|
|   sub-child| true|
|      cousin|false|
+------------+-----+


scala>
0 голосов
/ 13 декабря 2018

Давайте посмотрим пример с искровой оболочкой.Надеюсь, это поможет вам.

scala> import spark.implicits._
import spark.implicits._

scala> val df0 = 
spark.sparkContext.parallelize(List(1,2,1,3,3,2,1)).toDF("number")
df0: org.apache.spark.sql.DataFrame = [number: int]

scala> val list = List(1,2,3)
list: List[Int] = List(1, 2, 3)


scala> val dfFiltered = for (number <- list) yield { df0.filter($"number" === number)}
dfFiltered: List[org.apache.spark.sql.Dataset[org.apache.spark.sql.Row]] = List([number: int], [number: int], [number: int])

scala> dfFiltered(0).show
+------+
|number|
+------+
|     1|
|     1|
|     1|
+------+


scala> dfFiltered(1).show
+------+
|number|
+------+
|     2|
|     2|
+------+


scala> dfFiltered(2).show
+------+
|number|
+------+
|     3|
|     3|
+------+
0 голосов
/ 14 декабря 2018

AFAIK isin может использоваться в этом случае, например, в следующем примере:

import spark.implicits._

val colorStringArr = "red,yellow,blue".split(",")
val colorDF =
  List(
    "red",
    "yellow",
    "purple"
  ).toDF("color")
// to derive a column using a list
colorDF.withColumn(
  "is_primary_color",
  col("color").isin(colorStringArr: _*)
).show()


     println( "if you don't want derived column and directly want to   filter using a list with isin then .. ")
    colorDF.filter(col("color").isin(colorStringArr: _*)).show

Результат:

+------+----------------+
| color|is_primary_color|
+------+----------------+
|   red|            true|
|yellow|            true|
|purple|           false|
+------+----------------+

, если вы не хотите, чтобы производный столбец инапрямую хотите фильтровать, используя список с isin затем ....

+------+
| color|
+------+
|   red|
|yellow|
+------+
0 голосов
/ 13 декабря 2018

Вы должны применить последующие фильтры к результату предыдущего фильтра, а не к df:

val x = ("parent,child,sub-child").split(",")
var df1 = df
x.map(eachvalue <- {
    df1 = df1.filter(col("root").contains(eachvalue))
}

df1 после того, как к операции карты будут применены все фильтры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...