使用Spark按条件筛选数据框。

3

I have a data frame which looks like

scala> val df = sc.parallelize(Seq(("User 1","X"), ("User 2", "Y"), ("User 3", "X"), ("User 2", "E"), ("User 3", "E"))).toDF("user", "event")

scala> df.show
+------+-----+
|  user|event|
+------+-----+
|User 1|    X|
|User 2|    Y|
|User 3|    X|
|User 2|    E|
|User 3|    E|
+------+-----+

我想找到所有拥有事件“X”但没有事件“E”的用户。
在这种情况下,只有“用户1”符合条件,因为它没有事件“E”条目。我该如何使用Spark API实现呢?

创建两个名为 X 和 E 的数据框,并使用不等于条件将它们连接起来。 - undefined_variable
4个回答

4

左连接可以使用:

val xDF = df.filter(col("event") === "X")
val eDF = df.filter(col("event") === "E")
val result = xDF.as("x").join(eDF.as("e"), List("user"), "left_outer").where(col("e.event").isNull).select(col("x.user"))

结果是:

+------+
|user  |
+------+
|User 1|
+------+

连接操作开销较大。 - Balaji Reddy

4
您可以通过事件集合对用户进行分组,然后基于特定条件过滤适当用户的事件。
val result = df.groupBy("user")
    .agg(collect_list("event")
    .as("events"))
    .filter( p => p.getList(1).contains("X") && !p.getList(1).contains("E"))

3
val tmp = df.groupBy("user").pivot("event").count
tmp.show
+------+----+----+----+
|  user|   E|   X|   Y|
+------+----+----+----+
|User 2|   1|null|   1|
|User 3|   1|   1|null|
|User 1|null|   1|null|
+------+----+----+----+
tmp.filter(  ($"X" isNotNull) and ($"E" isNull) ).show
+------+----+---+----+
|  user|   E|  X|   Y|
+------+----+---+----+
|User 1|null|  1|null|
+------+----+---+----+
tmp.filter(  ($"X" isNotNull) and ($"E" isNull) ).select("user","X").show 
+------+---+
|  user|  X|
+------+---+
|User 1|  1|
+------+---+

希望这能有所帮助。


已添加 tmp.filter(($"X"不为空) and ($"E"为空)).select("user","X").show! 感谢您的建议。 - shengshan zhang

1
你可以计算每个用户的行数,计算每个用户和事件的行数,然后过滤掉那些计数相等且事件列具有X值的行。
import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions.Window
df.withColumn("count", count($"user").over(Window.partitionBy("user")))
    .withColumn("distinctCount", count($"user").over(Window.partitionBy("user", "event")))
    .filter($"count" === $"distinctCount" && $"event" === "X")
    .drop("count", "distinctCount")

你应该获得想要的结果

我希望这个答案有所帮助


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接