简体   繁体   English

过滤Spark数据帧中的多个列

[英]Filtering on multiple columns in Spark dataframes

Suppose I have a dataframe in Spark as shown below - 假设我在Spark中有一个数据帧,如下所示 -

val df = Seq(
(0,0,0,0.0),
(1,0,0,0.1),
(0,1,0,0.11),
(0,0,1,0.12),
(1,1,0,0.24),
(1,0,1,0.27),
(0,1,1,0.30),
(1,1,1,0.40)
).toDF("A","B","C","rate")

Here is how it looks like - 这是它的样子 -

scala> df.show()
+---+---+---+----+
|  A|  B|  C|rate|
+---+---+---+----+
|  0|  0|  0| 0.0|
|  1|  0|  0| 0.1|
|  0|  1|  0|0.11|
|  0|  0|  1|0.12|
|  1|  1|  0|0.24|
|  1|  0|  1|0.27|
|  0|  1|  1| 0.3|
|  1|  1|  1| 0.4|
+---+---+---+----+

A,B and C are the advertising channels in this case. 在这种情况下,A,B和C是广告渠道。 0 and 1 represent absence and presence of channels respectively. 0和1分别表示通道的缺失和存在。 2^3 shows 8 combinations in the data-frame. 2 ^ 3显示数据帧中的8种组合。

I want to filter records from this data-frame that shows presence of 2 channels at a time( AB, AC, BC) . 我想从这个数据帧中过滤记录,一次显示2个通道(AB,AC,BC)。 Here is how I want my output to be - 以下是我希望输出的方式 -

+---+---+---+----+
|  A|  B|  C|rate|
+---+---+---+----+
|  1|  1|  0|0.24|
|  1|  0|  1|0.27|
|  0|  1|  1| 0.3|
+---+---+---+----+

I can write 3 statements to get the output by doing - 我可以编写3个语句来获取输出 -

scala> df.filter($"A" === 1 && $"B" === 1 && $"C" === 0).show()
+---+---+---+----+
|  A|  B|  C|rate|
+---+---+---+----+
|  1|  1|  0|0.24|
+---+---+---+----+


scala> df.filter($"A" === 1 && $"B" === 0  && $"C" === 1).show()
+---+---+---+----+
|  A|  B|  C|rate|
+---+---+---+----+
|  1|  0|  1|0.27|
+---+---+---+----+


scala> df.filter($"A" === 0 && $"B" === 1 && $"C" === 1).show()
+---+---+---+----+
|  A|  B|  C|rate|
+---+---+---+----+
|  0|  1|  1| 0.3|
+---+---+---+----+

However, I want to achieve this using either a single statement that does my job or a function that helps me get the output. 但是,我想使用一个完成我的工作的语句或一个帮助我获得输出的函数来实现这一点。 I was thinking of using a case statement to match the values. 我在考虑使用case语句来匹配值。 However in general my dataframe might consist of more than 3 channels - 但一般来说,我的数据框可能包含3个以上的频道 -

scala> df.show()
+---+---+---+---+----+
|  A|  B|  C|  D|rate|
+---+---+---+---+----+
|  0|  0|  0|  0| 0.0|
|  0|  0|  0|  1| 0.1|
|  0|  0|  1|  0| 0.1|
|  0|  0|  1|  1|0.59|
|  0|  1|  0|  0| 0.1|
|  0|  1|  0|  1|0.89|
|  0|  1|  1|  0|0.39|
|  0|  1|  1|  1| 0.4|
|  1|  0|  0|  0| 0.0|
|  1|  0|  0|  1|0.99|
|  1|  0|  1|  0|0.49|
|  1|  0|  1|  1| 0.1|
|  1|  1|  0|  0|0.79|
|  1|  1|  0|  1| 0.1|
|  1|  1|  1|  0| 0.1|
|  1|  1|  1|  1| 0.1|
+---+---+---+---+----+

In this scenario I would want my output as - 在这种情况下,我希望我的输出为 -

scala> df.show()
+---+---+---+---+----+
|  A|  B|  C|  D|rate|
+---+---+---+---+----+
|  0|  0|  1|  1|0.59|
|  0|  1|  0|  1|0.89|
|  0|  1|  1|  0|0.39|
|  1|  0|  0|  1|0.99|
|  1|  0|  1|  0|0.49|
|  1|  1|  0|  0|0.79|
+---+---+---+---+----+

which shows rates for paired presence of channels => (AB, AC, AD, BC, BD, CD). 其中显示了成对存在的通道的速率=>(AB,AC,AD,BC,BD,CD)。

Kindly help. 请帮助。

One way could be to sum the columns and then filter only when the result of the sum is 2. 一种方法可以是对列进行求和,然后仅在和的结果为2时进行过滤。

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

df.withColumn("res", $"A" + $"B" + $"C").filter($"res" === lit(2)).drop("res").show

The output is: 输出是:

+---+---+---+----+
|  A|  B|  C|rate|
+---+---+---+----+
|  1|  1|  0|0.24|
|  1|  0|  1|0.27|
|  0|  1|  1| 0.3|
+---+---+---+----+

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM