Scala 如何从Spark中的数据帧创建EdgeRDD
我在spark中有一个数据帧。每一行代表一个人,我想检索他们之间可能的联系。拥有链接的规则是,对于每个可能的对,如果它们具有相同的prop1:String,并且prop2:Int的绝对差值小于5,则链接存在。我正在试图了解使用数据帧完成此任务的最佳方法 我正在尝试检索索引RDD:Scala 如何从Spark中的数据帧创建EdgeRDD,scala,apache-spark,spark-dataframe,Scala,Apache Spark,Spark Dataframe,我在spark中有一个数据帧。每一行代表一个人,我想检索他们之间可能的联系。拥有链接的规则是,对于每个可能的对,如果它们具有相同的prop1:String,并且prop2:Int的绝对差值小于5,则链接存在。我正在试图了解使用数据帧完成此任务的最佳方法 我正在尝试检索索引RDD: val idusers = people.select("ID") .rdd .map(r => r(0).asInstance
val idusers = people.select("ID")
.rdd
.map(r => r(0).asInstanceOf[Int])
.zipWithIndex
val prop1users = people.select("ID")
.rdd
.map(r => (r(0).asInstanceOf[Int], r(1).asInstanceOf[String]))
val prop2users = people.select("ID")
.rdd
.map(r => (r(0).asInstanceOf[Int], r(2).asInstanceOf[Int]))
然后开始删除重复项,如:
var links = idusers
.join(idusers)
.filter{ case (v1, v2) => v2._1 != v2._2 }
但后来我被困在检查prop1。。。无论如何,有没有一种方法可以仅仅使用数据帧来完成所有这些步骤?假设您有这样的方法:
val sqlc : SQLContext = ???
case class Person(id: Long, country: String, age: Int)
val testPeople = Seq(
Person(1, "Romania" , 15),
Person(2, "New Zealand", 30),
Person(3, "Romania" , 17),
Person(4, "Iceland" , 20),
Person(5, "Romania" , 40),
Person(6, "Romania" , 44),
Person(7, "Romania" , 45),
Person(8, "Iceland" , 21),
Person(9, "Iceland" , 22)
)
val people = sqlc.createDataFrame(testPeople)
可以使用重命名的列创建第一个自连接奇迹,以避免自连接中的列冲突:
val peopleR = people
.withColumnRenamed("id" , "idR")
.withColumnRenamed("country", "countryR")
.withColumnRenamed("age" , "ageR")
现在,您可以将dataframe与自交换对和循环边连接起来:
import org.apache.spark.sql.functions._
val relations = people.join(peopleR,
(people("id") < peopleR("idR")) &&
(people("country") === peopleR("countryR")) &&
(abs(people("age") - peopleR("ageR")) < 5))
relations.show()
现在将输出:
+---+-------+---+---+--------+----+
| id|country|age|idR|countryR|ageR|
+---+-------+---+---+--------+----+
| 1|Romania| 15| 3| Romania| 17|
| 4|Iceland| 20| 8| Iceland| 21|
| 4|Iceland| 20| 9| Iceland| 22|
| 5|Romania| 40| 6| Romania| 44|
| 6|Romania| 44| 7| Romania| 45|
| 8|Iceland| 21| 9| Iceland| 22|
+---+-------+---+---+--------+----+
和edges.toLocalIterator.foreach(println)
将输出:
Edge(1,3,())
Edge(4,8,())
Edge(4,9,())
Edge(5,6,())
Edge(6,7,())
Edge(8,9,())
非常宝贵的反馈,谢谢你。。。只是想知道:拥有你的id栏的最佳方式是什么?实际上,我从数据库中提取数据时,数据库中没有它。。。我可以添加一个新列来索引我的数据帧吗?@digitaldust您可以使用
monoticallyincreasingid()
函数vertexid是否需要从零开始或保持一致?i、 e.如果我有一个较低的值1020210,Spark会创建它认为缺少的1020209节点吗?这是您演示如何创建EdgeRDD后的最后一点。。。假设您的示例中有数据帧,那么如何创建VertexRDD?
Edge(1,3,())
Edge(4,8,())
Edge(4,9,())
Edge(5,6,())
Edge(6,7,())
Edge(8,9,())