根据列和值的序列动态生成过滤器

时间:2018-09-17 20:56:33

标签: scala apache-spark

假设我有一个列序列,并且我也有一个相同长度的序列,对应于每个列的特定值。

我想过滤一个数据帧,使其每列等于序列中的相应值。

遍历列并迭代过滤似乎效率低下,但由于我曾经是R程序员,所以我可能不喜欢for循环。

是for循环是解决此问题的最佳方法,还是有一种很好的方法将序列转换为可以像这样进行过滤的列?

代码类似于:

val df = data.frame(a=1:3,b=1:3,c=1:3) //use R syntax here for brevity
val cols = Seq($"a",$"b",$"c")
val vals = Seq(1, 2, 3)
val filteredDf = df
cols.map(case(col, i) => filteredDf = filteredDf.filter(col = vals[i]))

1 个答案:

答案 0 :(得分:2)

您可以将列和值的每个元组映射到一个条件中,然后将reduceColumn.and函数一起使用以创建用于检查所有列的单个条件。

然后,在这种情况下使用filter

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

val condition = cols.zip(vals)
  .map { case (c, v) => c.equalTo(lit(v)) }
  .reduce(_ and _)

val result = df.filter(condition)

例如:

df.show()
// +---+---+---+
// |  a|  b|  c|
// +---+---+---+
// |  1|  2|  3|
// |  1|  3|  5|
// +---+---+---+

result.show()
// +---+---+---+
// |  a|  b|  c|
// +---+---+---+
// |  1|  2|  3|
// +---+---+---+