基于Graphx/Spark的pyspark父子关系模型
我有一个包含(子、父)实体的数据集。我需要从数据集中找到每个孩子的最终父母。我的数据集有130万条记录。样本数据如下所示基于Graphx/Spark的pyspark父子关系模型,pyspark,spark-graphx,Pyspark,Spark Graphx,我有一个包含(子、父)实体的数据集。我需要从数据集中找到每个孩子的最终父母。我的数据集有130万条记录。样本数据如下所示 c-1, p-1 p-1, p-2 p-2, p-3 p-3, p-4 在上述样本数据中,c-1的最终母体是p-4,p-1的最终母体是p-4,依此类推。 有时,为了找到孩子的最终父母,我需要递归地遍历多个级别。 这就是我迄今为止所尝试的 我试图创建一个spark DF,并试图递归地找到 每个孩子的父母。但这种方法需要很长时间 我试图创造 可应用于数据集每一行的自定义项。但我
c-1, p-1
p-1, p-2
p-2, p-3
p-3, p-4
在上述样本数据中,c-1的最终母体是p-4,p-1的最终母体是p-4,依此类推。
有时,为了找到孩子的最终父母,我需要递归地遍历多个级别。
这就是我迄今为止所尝试的
关于如何解决这个问题有什么建议吗?为了解决您提到的两个问题,在spark中使用Graphx Pregel API实现CTE可能会有帮助 下面是一个示例代码
//setup & call the pregel api
def calcTopLevelHierarcy(vertexDF: DataFrame, edgeDF: DataFrame): RDD[(Any,(Int,Any,String,Int,Int))] = {
// create the vertex RDD
// primary key, root, path
val verticesRDD = vertexDF
.rdd
.map{x=> (x.get(0),x.get(1) , x.get(2))}
.map{ x => (MurmurHash3.stringHash(x._1.toString).toLong, ( x._1.asInstanceOf[Any], x._2.asInstanceOf[Any] , x._3.asInstanceOf[String]) ) }
// create the edge RDD
// top down relationship
val EdgesRDD = edgeDF.rdd.map{x=> (x.get(0),x.get(1))}
.map{ x => Edge(MurmurHash3.stringHash(x._1.toString).toLong,MurmurHash3.stringHash(x._2.toString).toLong,"topdown" )}
// create graph
val graph = Graph(verticesRDD, EdgesRDD).cache()
val pathSeperator = """/"""
// initialize id,level,root,path,iscyclic, isleaf
val initialMsg = (0L,0,0.asInstanceOf[Any],List("dummy"),0,1)
// add more dummy attributes to the vertices - id, level, root, path, isCyclic, existing value of current vertex to build path, isleaf, pk
val initialGraph = graph.mapVertices((id, v) => (id,0,v._2,List(v._3),0,v._3,1,v._1) )
val hrchyRDD = initialGraph.pregel(initialMsg,
Int.MaxValue,
EdgeDirection.Out)(
setMsg,
sendMsg,
mergeMsg)
// build the path from the list
val hrchyOutRDD = hrchyRDD.vertices.map{case(id,v) => (v._8,(v._2,v._3,pathSeperator + v._4.reverse.mkString(pathSeperator),v._5, v._7 )) }
hrchyOutRDD
}
在方法calcTopLevelHierarcy()中,您可以传入数据帧(这解决了您的第二点)
下面是一个非常好的示例代码。请看一看
希望,这有帮助