Scala 如何使用graph.fromEdgeTuples从数组[(任意,任意)]创建图形

Scala 如何使用graph.fromEdgeTuples从数组[(任意,任意)]创建图形,scala,apache-spark,apache-spark-sql,spark-graphx,Scala,Apache Spark,Apache Spark Sql,Spark Graphx,我对spark非常陌生,但我想从蜂巢表中获得的关系创建一个图表。我找到了一个函数,该函数应该在不定义顶点的情况下允许这样做,但我无法让它工作 我知道这不是一个可复制的示例,但以下是我的代码: import org.apache.spark.SparkContext import org.apache.spark.graphx._ import org.apache.spark.rdd.RDD val sqlContext= new org.apache.spark.sql.hive.HiveCo

我对spark非常陌生,但我想从蜂巢表中获得的关系创建一个图表。我找到了一个函数,该函数应该在不定义顶点的情况下允许这样做,但我无法让它工作

我知道这不是一个可复制的示例,但以下是我的代码:

import org.apache.spark.SparkContext
import org.apache.spark.graphx._
import org.apache.spark.rdd.RDD
val sqlContext= new org.apache.spark.sql.hive.HiveContext(sc)
val data = sqlContext.sql("select year, trade_flow, reporter_iso, partner_iso, sum(trade_value_us) from comtrade.annual_hs where length(commodity_code)='2' and not partner_iso='WLD' group by year, trade_flow, reporter_iso, partner_iso").collect()
val data_2010 = data.filter(line => line(0)==2010)
val couples = data_2010.map(line=>(line(2),line(3)) //country to country 

val graph = Graph.fromEdgeTuples(couples, 1)
最后一行生成以下错误:

val graph = Graph.fromEdgeTuples(sc.parallelize(couples), 1)
<console>:31: error: type mismatch;
found   : Array[(Any, Any)]
required: Seq[(org.apache.spark.graphx.VertexId,org.apache.spark.graphx.VertexId)]
Error occurred in an application involving default arguments.
val graph = Graph.fromEdgeTuples(sc.parallelize(couples), 1)

如何转换为合适的格式

首先,您不能将
String
用作
VertexId
,因此必须将标签映射到
Long
。然后,我们需要准备从标签到id的映射。只要唯一值的数量相对较少,最简单的方法就是创建广播变量:

val idMap = sc.broadcast(couples // -> Array[(Any, Any)]
  // Make sure we use String not Any returned from Row.apply
  // And convert to Seq so we can flatten results
  .flatMap{case (x: String, y: String) => Seq(x, y)} // -> Array[String]
  // Get different keys
  .distinct // -> Array[String]
  // Create (key, value) pairs
  .zipWithIndex  // -> Array[(String, Int)]
  // Convert values to Long so we can use it as a VertexId
  .map{case (k, v) => (k, v.toLong)}  // -> Array[(String, Long)]
  // Create map
  .toMap) // -> Map[String,Long]
接下来,我们可以使用上述方法执行映射:

val edges: RDD[(VertexId, VertexId)] = sc.parallelize(couples
  .map{case (x: String, y: String) => (idMap.value(x), idMap.value(y))}
)
最后我们得到一个图表:

val graph = Graph.fromEdgeTuples(edges, 1)

哇,谢谢!我明天第一件事就是试试这个。你介意详细说明一下你使用的不同方法吗?我明白了大概的意思,但如果我能够理解每一步,而不是仅仅复制这一步,那将是非常有用的。当然,我已经添加了一些注释和类型信息。完全有效,非常感谢您的解释。你知道这是否可以用Spark来可视化一个图形,我使用的是控制台,所以我想没有图形界面?我对此表示怀疑。您可以随时收集感兴趣的子图,并使用通用图形处理库,如Gephi。如果您感到厌烦,我有一个新问题:-)
val graph = Graph.fromEdgeTuples(edges, 1)