使用数据框的子集和 spark/scala 中的两个特定字段过滤数据框

Filter a Dataframe using a subset of it and two specific fields in spark/scala

我有一个 Scala/Spark 问题。我正在使用 Spark 2.1.1。 我有一个看起来像这样的数据框:

client transaction amount machine
0000001 transaction1 -0.010000 user000000001
0000002 transaction2 0.010000 user000000001
0000002 transaction2 0.010000 user000000002
0000002 transaction2 0.010000 user000000003
0000003 transaction3 -0.010000 user000000004
0000003 transaction3 -0.010000 user000000002
0000003 transaction3 -0.010000 user000000003
0000003 transaction3 -0.010000 user000000011
0000001 transaction4 0.010000 user000000011

此外,我还有另一个 Dataframe,一个子集:

client transaction amount machine
0000002 transaction2 0.010000 user000000001
0000002 transaction2 0.010000 user000000002
0000002 transaction2 0.010000 user000000003
0000003 transaction3 -0.010000 user000000004
0000003 transaction3 -0.010000 user000000002
0000003 transaction3 -0.010000 user000000003
0000003 transaction3 -0.010000 user000000011

如何使用第二个过滤第一个?我不知道是否可以使用减法选项但使用两个字段作为条件来过滤数据框。或者一种执行 join/union 但使用两种不同条件的方法。为什么要使用两个字段作为条件?好吧,如果你分析 table,你可以看到 transaction2 和 transaction3 用不同的机器标识符重复了 n 次。我只需要保留具有唯一事务的行,其中机器与非重复事务机器匹配。我的意思是,我需要这样的 table:

client transaction amount machine
0000001 transaction1 -0.010000 user000000001
0000002 transaction2 0.010000 user000000001
0000003 transaction3 -0.010000 user000000011
0000001 transaction4 0.010000 user000000011

非常感谢您对此的帮助和指导!

如果要从第一个数据帧中减去子数据帧,可以使用左反连接,如下所示:

dataframe.join(subset, dataframe.columns, "left_anti")

给定你的输入数据框和你的子集,你将得到:

+-------+------------+------+-------------+
|client |transaction |amount|machine      |
+-------+------------+------+-------------+
|0000001|transaction1|-0.01 |user000000001|
|0000001|transaction4|0.01  |user000000011|
+-------+------------+------+-------------+

然后您可以获得 machine 列并使用内部联接来过滤第一个数据框中的重复项。完整代码如下:

dataframe.join(subset, dataframe.columns, "left_anti")
  .select("machine")
  .join(dataframe, Seq("machine"))

您将得到预期的结果:

+-------------+-------+------------+------+
|machine      |client |transaction |amount|
+-------------+-------+------------+------+
|user000000001|0000001|transaction1|-0.01 |
|user000000001|0000002|transaction2|0.01  |
|user000000011|0000003|transaction3|-0.01 |
|user000000011|0000001|transaction4|0.01  |
+-------------+-------+------------+------+

但是,对于您的情况,我认为您不需要构建子集数据框,您可以仅使用第一个数据框来获得结果,如下所示:

dataframe.groupBy("transaction")
  .agg(count("transaction").as("total"), first("machine").as("machine"))
  .filter(col("total") === 1)
  .select("machine")
  .join(dataframe, Seq("machine"))