• scala combineByKey用法说明


    语法是:

    combineByKey[C](  

    createCombiner: V => C,  

    mergeValue: (C, V) => C,  

    mergeCombiners: (C, C) => C

    标记一下:(因为有很多同样的字母,方便说明我就按照字母+数字标记一下)

    语法说明:(不复制网上的,我按照我的理解大白话说明)

    1,combineByKey 中的byKey 就是按照键来处理,你就默认 他丫知道 哪些键是一样的,他会在每个分区自动归类同样的键,你就操心怎么处理值就行了, 总之就是:对相同K,把V合并成一个集合

    2,每条数据会被遍历,如果某条数据的键 是第一遇到,就用createCombiner  处理,否则用mergeValue (你要是第一次去银行存钱,流程就是先开户,  下一次去了你存钱就是其他的流程了->直接存钱就行)

    3,createCombiner  和  mergeValue 处理单个分区中数据,  mergeCombiners是每个分区处理完了 合并数据使用

    例子说明:Fred 和 william 二个人  数语外分数 分别是 val scores = Array(("Fred", 88), ("Fred", 95), ("Fred", 91), ("Wilma", 93), ("Wilma", 95), ("Wilma", 98))

    求他们各自的平均成绩

    思路是: 通过combineByKey函数把按照人分组 求出 他们的总分  和科目数   ,然后用map函数 除一下就完事 

    操作1:为了模拟多个分区 我创建2个分区

      

      

    操作2: 把每个分区的结果按照名字 计算分数总和 科目数量

     

      说明:参照语法图

          (左图)                                                                                                                   (右图

       首先:各个分区的兄弟们先干活

        第一个分区遍历开始: 数据为

            --> 处理(Fred,88), 因为是第一次遇到键“Fred”, 所以调用createCombiner方法 (v)=> (v,1)  ; 这里就是(88) => (88,1)

             --> 处理(Fred,95),不是第一次遇到键“Fred”,调用mergeValue方法(acc:(Int,Int),v)=>(acc._1+v,acc._2+1),: 这里就是((88,1),95)=>(88+95, 1+1)

            --> 处理(Fred,91),不是第一次遇到键“Fred”,调用mergeValue方法(acc:(Int,Int),v)=>(acc._1+v,acc._2+1),: 这里就是((88+95,1+1),91)=>(88+95+91, 1+1+1)

        第一个分区遍历结束:返回(274,3)  (注意一个分区中可能有很多不一样的键值对,我这里碰巧只有fred一个人 ,也许还有张三(**,**), 李四(**,**))(程序本来就按照键BYkeys分组了,所以不用担心混淆了键)

         

       

       第二个分区遍历开始: 数据为:

            --> 处理(Wilma,93), 因为是第一次遇到键“Fred”, 所以调用createCombiner方法 (v)=> (v,1)  ; 这里就是(93) => (93,1)

             --> 处理(Wilma,95),不是第一次遇到键“Fred”,调用mergeValue方法(acc:(Int,Int),v)=>(acc._1+v,acc._2+1),: 这里就是((93,1),95)=>(93+95, 1+1)

            --> 处理(Wilma,98),不是第一次遇到键“Fred”,调用mergeValue方法(acc:(Int,Int),v)=>(acc._1+v,acc._2+1),: 这里就是((93+95,1+1),98)=>(93+95+98, 1+1+1)

        第一个分区遍历结束:返回(286,3) 

      然后:各个分区兄弟干完了   汇总处理

        由于我的数据少,没有模拟到比如分区 1  和分区2 都有 Fred的成绩, 他三科成绩在第一个分区就全部统计到了。

          假如 分区一返回的是fred信息(274,3), 

            分区二返回是 fred的体育成绩(80,1), 和wilma的三科成绩(286,3)

          汇总后开始调用mergeCombiners: (C, C) => C 方法

             (acc1:(Int,Int),acc2:(Int,Int))=>(acc1._1+acc2._1,acc1._2+acc2._2)) 执行到就应该是  ((274,3),(80,1)) =>(274+80 , 3+1)     (fred的结果)

                                                         。。。。。。。。。。。。=>(286,3)   (WILMA的结果)

    操作3: 把分数总和 和  科目数量除一下 得到平均成绩

  • 相关阅读:
    UVA 11174 Stand in a Line,UVA 1436 Counting heaps —— (组合数的好题)
    UVA 1393 Highways,UVA 12075 Counting Triangles —— (组合数,dp)
    【Same Tree】cpp
    【Recover Binary Search Tree】cpp
    【Binary Tree Zigzag Level Order Traversal】cpp
    【Binary Tree Level Order Traversal II 】cpp
    【Binary Tree Level Order Traversal】cpp
    【Binary Tree Post order Traversal】cpp
    【Binary Tree Inorder Traversal】cpp
    【Binary Tree Preorder Traversal】cpp
  • 原文地址:https://www.cnblogs.com/spicy/p/9722935.html
Copyright © 2020-2023  润新知