当前位置: 首页 > 知识库问答 >
问题:

ApacheSpark-生成配对列表

魏冷勋
2023-03-14

给定一个包含以下格式数据的大文件(V1,V2,…,VN)

2,5
2,8,9
2,5,8
...

我正在尝试使用Spark获得一个类似于下面的配对列表

((2,5),2)
((2,8),2)
((2,9),1)
((8,9),1)
((5,8),1)

我尝试了针对一个较旧的问题所提到的建议,但我遇到了一些问题。例如,

val dataRead = sc.textFile(inputFile)
val itemCounts = dataRead
  .flatMap(line => line.split(","))
  .map(item => (item, 1))
  .reduceByKey((a, b) => a + b)
  .cache()
val nums = itemCounts.keys
  .filter({case (a) => a.length > 0})
  .map(x => x.trim.toInt)
val pairs = nums.flatMap(x => nums2.map(y => (x,y)))

我得到了错误,

scala> val pairs = nums.flatMap(x => nums.map(y => (x,y)))
<console>:27: error: type mismatch;
 found   : org.apache.spark.rdd.RDD[(Int, Int)]
 required: TraversableOnce[?]
       val pairs = nums.flatMap(x => nums.map(y => (x,y)))
                                             ^

有人能告诉我哪些地方我可能做得不对,或者有什么更好的方法可以达到同样的效果?非常感谢。

共有3个答案

虞俊美
2023-03-14

基本上,您正在尝试将(Int, Int)上的WordCount作为键,而不是常见的示例String

所以这里的目标是将您的行转换为(Int, Int)元组:

val pairs = sc.textFile(inputFile)
              .map(line => line.split(","))
              .flatMap(a => a.sliding(2))
              .map(a => (a(0).toInt, a(1).toInt) -> 1)
              .reduceByKey(_ + _)
姜智渊
2023-03-14

我不确定你需要什么,我从每一行中提取数字对滑动窗口,例如从第2,8,9行中提取2对:(2,8)

  val dataRead = sc.textFile(this.getClass.getResource("/text.txt").getFile)

  // Extract tuples from each line
  val tuples: RDD[(Int, Int)] = dataRead.flatMap(_.split(",").sliding(2)).map {
    case Array(l, r) => (l.toInt, r.toInt)
  }  

  val count = tuples.countByValue()

  count.foreach(println)

输出

((2,5),2)
((8,9),1)
((5,8),1)
((2,8),1)
谢英耀
2023-03-14

你可以使用数组的组合方法来达到这个目的。

val dataRead = sc.textFile(inputFile)
// "2,5"
// "2,8,9"
// "2,5,8" 
//  ...

val combinations = dataRead.flatMap { line =>
        line.split(",")        // "2,8,9" => Array(2,8,9)
            .combinations(2)   // Iterator
            .toSeq             // ~ Array(Array(2,8), Array(2,9), Array(8,9))
            .map{ case arr => arr(0) -> arr(1) }  // Array((2,8), (2,9), (8,9))
}

// Array((2,5), (2,8), (2,9), (8,9), (2,5), (2,8), (5, 8), ...)

val result = combinations.map(item => item -> 1) // Array(((2,5),1), ((2,9),1), ...)
                         .reduceByKey(_ + _)   
// Array(((2,5),2), ((2,8),2), ((2,9),1), ((8,9),1), ((5,8),1) ....) 
// order may be different.
 类似资料:
  • 我有一个项目的RDD,还有一个函数 。 收集RDD的两个小样本,然后这两个数组。这很好,但无法扩展。 有什么想法吗? 谢谢 编辑:下面是如何压缩每个分区中具有不同项数的两个示例: 关键是,虽然RDD的. zip方法不接受大小不等的分区,但迭代器的. zip方法接受(并丢弃较长迭代器的剩余部分)。

  • 当我们将一个对象作为键插入到一个映射中时,它的哈希代码就会生成。但如果我的密钥是对象列表,那么,它是列表中所有对象哈希代码的总和吗? 请帮助理解。

  • 1、创建 list 的方式 之前经过我们的学习,都知道如何创建一个 list ,可是有些情况,用赋值的形式创建一个 list 太麻烦了,特别是有规律的 list ,一个一个的写,一个一个赋值,太麻烦了。比如要生成一个有 30 个元素的 list ,里面的元素为 1 - 30 。我们可以这样写: # -*- coding: UTF-8 -*- list1=list ( range (1,31) )

  • 我有一个基于maven的scala/java混合应用程序,可以提交spar作业。我的应用程序jar“myapp.jar”在lib文件夹中有一些嵌套的jar。其中之一是“common.jar”。我在清单文件中定义了类路径属性,比如。Spark executor抛出在客户端模式下提交应用程序时出错。类(com/myapp/common/myclass.Class)和jar(common.jar)在那里

  • 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。 举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用range(1, 11): >>> range(1, 11) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 但如果要生成[1x1, 2x2, 3x3, ..., 10

  • 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。 举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)): >>> list(range(1, 11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 但如果要生成[1x1, 2x2,