Spark - 组合而不重复

时间:2015-06-07 21:54:27

标签: scala apache-spark combinations rdd

我试图在不重复文本文件的情况下进行所有行组合。

示例:

  1. 1
  2. 2
  3. 2
  4. 1
  5. 1
  6. 结果:

    • 第1行第2行=(1,2)
    • 第1行第3行=(1,2)
    • 第1行第4行=(1,1)
    • 第1行第5行=(1,1)
    • 第2行第3行=(2,2)
    • 第2行第4行=(2,1)
    • 第2行第5行=(2,1)
    • 第3行第4行=(2,1)
    • 第3行第5行=(2,1)
    • 第4行第5行=(1,1)

    考虑(x,y),if(x!= y)0 else 1:

    • 0
    • 0
    • 1
    • 1
    • 1
    • 0
    • 0
    • 0
    • 0
    • 1

    我有以下代码:

    def processCombinations(rdd: RDD[String]) = {
        rdd.mapPartitions({ partition => {
            var previous: String = null;
            if (partition.hasNext)
              previous = partition.next
    
            for (element <- partition) yield {
              if (previous == element)
                "1"
              else
                "0"
            }
          }
        })
      }
    

    上面的代码片段是我RDD的第一个元素的组合,换句话说:(1,2)(1,2)(1,1)(1,1)。

    问题是:此代码仅适用于ONE PARTITION。我想用很多分区做这个工作,我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

目前还不是很清楚你想要什么作为输出,但这会再现你的第一个例子,并直接转换为Spark。它生成组合,但只有在原始列表中第一个元素的索引小于第二个元素的索引的情况下,我认为你要求它。

val r = List(1,2,2,1,1)
val z = r zipWithIndex

z.flatMap(x=>z.map(y=>(x,y))).collect{case(x,y) if x._2 < y._2 => (x._1, y._1)}
//List((1,2), (1,2), (1,1), (1,1), (2,2), (2,1), (2,1), (2,1), (2,1), (1,1))

或者,作为理解

for (x<-z; y<-z; if x._2 < y._2) yield (x._1, y._1)

答案 1 :(得分:0)

此代码使用递归计算组合而不重复。它有两个参数:组合元素的数量和元素列表。

它按以下方式工作:对于给定列表:1,2,3,4,5 =&gt;第一个组合需要4个第一个元素。然后它生成与列表的最后一个元素5的其他组合。当列表中没有剩余的元素时,它向后移动一个位置(第三个位置)并从下一个元素生成更多的组合:1,2,“4”,5。此操作以递归方式完成所有列表中的元素。

 class token_stream { //creates a stream of tokens 
 public:
    Token get(); //call to get token function 
    void putback(Token t); //call to token putback function
    void ignore(char a); // call to ignore bad tokens function

private:
    bool full{ false }; //is there a token in the buffer?
    Token buffer; //this is where putback token is stored
};