如何在Spark数据集中检测周期

时间:2018-07-27 15:01:16

标签: apache-spark apache-spark-dataset

我有一个Spark数据集,其中包含以下数据列:BuyerID和SellerID。我需要查找这些交易中是否存在周期。例如,A出售B,B出售A。在Spark中实现此目标的最佳方法是什么。为了使问题保持​​简单,数据集中还有其他一些列未提及。

2 个答案:

答案 0 :(得分:1)

  

我需要查找这些交易中是否存在周期。例如,A卖了B,而B卖了A。

使用这种非正式的循环定义(与正式的图论定义相反),在Spark中实现它几乎是微不足道的。排序标签:

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

val dfFromTo = df
  .withColumn("from", least($"BuyerID", $"SellerID"))
  .withColumn("to", greatest($"BuyerID", $"SellerID"))

汇总和过滤:

val cycles = dfFromTo.groupBy("from", "to").count.where($"count" > 1)

反联接从数据中删除周期:

dfFromTo.join(cycles, Seq("from", "to"), "leftanti")

从技术上讲,形式周期检测(例如A-> B-> C-> A)可以使用图处理原语(例如消息传递),但是通常无法很好地扩展,除非您对输入进行非常严格的限制

在这种情况下,最好使用优化的内核工具(如果可能)或专用的图形处理工具(与Spark中可用的SQL [graphframes]工具之上的废弃[GraphX]或piggy带支持相对) )。

答案 1 :(得分:0)

请尝试自动加入

val data = Seq((1,2),(3,4),(5,6),(2,1),(2,3)).toDF("Buyer","Seller")
 data.as("df1").join(data.as("df2"), $"df1.Buyer" === $"df2.Seller" and $"df1.Seller" === $"df2.Buyer")

输出

+-----+------+-----+------+
|Buyer|Seller|Buyer|Seller|
+-----+------+-----+------+
|    1|     2|    2|     1|
|    2|     1|    1|     2|
+-----+------+-----+------+