• GraphX中顶点和边的RDD操作


      GraphX 公开了存储在图中的顶点和边的 RDD 视图。但是,由于 GraphX 在优化的数据结构中维护了顶点和边,并且这些数据结构提供了额外的功能,所以顶点和边分别返回为 VertexRDDVertexRDD 和 EdgeRDDEdgeRDD。

    一、顶点RDD(VertexRDDs)

      VertexRDD[A] 扩展了 RDD[(VertexId, A)] 并添加了每个 VertexId 仅出现一次的附加约束。此外,VertexRDD[A] 表示一组顶点,每个顶点都具有类型 A 的属性。在内部,这是通过将顶点属性存储在可重用的哈希映射数据结构中来实现的。因此,如果两个 VertexRDD 是从相同的基础 VertexRDDVertexRDD 派生的(例如,通过 filter 或 mapValues),它们可以在恒定时间内连接,而无需哈希评估。为了利用这种索引数据结构,VertexRDDVertexRDD 开源了以下附加功能:

    class VertexRDD[VD] extends RDD[(VertexId, VD)] {
      // 过滤顶点集但保留内部索引
      def filter(pred: Tuple2[VertexId, VD] => Boolean): VertexRDD[VD]
    
      // 在不更改 id 的情况下转换值(保留内部索引) 
      def mapValues[VD2](map: VD => VD2): VertexRDD[VD2]
      def mapValues[VD2](map: (VertexId, VD) => VD2): VertexRDD[VD2]
    
      // 根据 VertexId 显示此集合唯一的顶点
      def minus(other: RDD[(VertexId, VD)])
    
      // 从这个集合中删除出现在另一个集合中的顶点 
      def diff(other: VertexRDD[VD]): VertexRDD[VD]
    
      // 利用内部索引来加速连接的连接运算符
      def leftJoin[VD2, VD3](other: RDD[(VertexId, VD2)])(f: (VertexId, VD, Option[VD2]) => VD3): VertexRDD[VD3]
      def innerJoin[U, VD2](other: RDD[(VertexId, U)])(f: (VertexId, VD, U) => VD2): VertexRDD[VD2]
    
      // 使用这个 RDD 上的索引来加速对输入 RDD 的 `reduceByKey` 操作。 
      def aggregateUsingIndex[VD2](other: RDD[(VertexId, VD2)], reduceFunc: (VD2, VD2) => VD2): VertexRDD[VD2]
    }

      例如,请注意过滤器运算符如何返回 VertexRDD。 过滤器实际上是使用 BitSet 实现的,从而重用索引并保留与其他 VertexRDD 进行快速连接的能力。 同样,mapValues 运算符不允许 map 函数更改 VertexId,从而可以重用相同的 HashMap 数据结构。 leftJoin 和 innerJoin 都能够识别何时连接来自同一个 HashMap 的两个 VertexRDD,并通过线性扫描而不是昂贵的点查找来实现连接。

      aggregateUsingIndex 运算符对于从 RDD[(VertexId, A)] 高效构造新的 VertexRDD 很有用。 从概念上讲,如果我在一组顶点上构造了一个 VertexRDD[B],它是某些 RDD[(VertexId, A)] 中顶点的超集,那么我可以重用索引来聚合,然后索引 RDD[(VertexId, A)]。 例如:

    val setA: VertexRDD[Int] = VertexRDD(sc.parallelize(0L until 100L).map(id => (id, 1)))
    val rddB: RDD[(VertexId, Double)] = sc.parallelize(0L until 100L).flatMap(id => List((id, 1.0), (id, 2.0)))
    // rddB有200个节点
    rddB.count
    val setB: VertexRDD[Double] = setA.aggregateUsingIndex(rddB, _ + _)
    //  setB有100个节点
    setB.count
    // 现在加入A和B会很快
    val setC: VertexRDD[Double] = setA.innerJoin(setB)((id, a, b) => a + b)

    二、边RDD(EdgeRDDs)

      扩展 RDD[Edge[ED]] 的 EdgeRDD[ED] 将边缘组织在使用 PartitionStrategy 中定义的各种分区策略之一进行分区的块中。 在每个分区内,边缘属性和邻接结构分别存储,以便在更改属性值时最大限度地重复使用。

      EdgeRDDEdgeRDD 开源的三个附加功能是:

    // 在保留结构的同时变换边缘属性
    def mapValues[ED2](f: Edge[ED] => ED2): EdgeRDD[ED2]
    // 反转边重用属性和结构
    def reverse: EdgeRDD[ED]
    // 加入两个使用相同分区策略分区的 `EdgeRDD`。
    def innerJoin[ED2, ED3](other: EdgeRDD[ED2])(f: (VertexId, VertexId, ED, ED2) => ED3): EdgeRDD[ED3]

      在大多数应用程序中,我们发现对 EdgeRDD 的操作是通过图运算符完成的,或者依赖于 RDD 基类中定义的操作。

  • 相关阅读:
    wpf中DataGrid自定义验证(包含BindingGroup)
    WPF博客地址分享
    ComboBox在WPF中的绑定示例:绑定项、集合、转换,及其源代码
    【windows phone】CollectionViewSource的妙用
    WPF之Binding深入探讨
    正确理解WPF中的TemplatedParent
    继续聊WPF——获取ComboBox中绑定的值
    WPF触发器(Trigger、DataTrigger、EventTrigger)
    jQuery和javaScript页面加载完成时触发的事件
    jQuery对象和dom对象的转换
  • 原文地址:https://www.cnblogs.com/Ao0216/p/15960664.html
Copyright © 2020-2023  润新知