【问题标题】:Spark - Scala : Return multiple <key, value> after processing one lineSpark - Scala:处理一行后返回多个 <key, value>
【发布时间】:2016-10-23 00:51:46
【问题描述】:

我有一个如下所示的数据集 -

0 -- 1,2,4
1 -- 0,4
2 -- 0,4
4 -- 2,1,0

我想读取每一行并将其转换为如下所示的内容

// 用于第 0 行 -- 1,2,4
(0,1)
(0,2)
(0,4)

// 对于第 1 行 -- 0,4
(0,1)
(1,4)

// 较小的数字总是出现在对中的第一个

即,读取以“--”分隔符分隔的每一行。所以我从数据集的第 1 行得到 0 和 1,2,4。之后,我想创建对。例如,(0,1) 将是转换后的地图的键,其值应为 2,4。

完成后,我希望能够按键对值进行分组

例如 (0,1)

将它们相交得到 4。

有可能做这样的事情吗?我的做法对吗?

到目前为止,我已经编写了以下代码-

var mapOperation = logData.map(x=>x.split("\t")).filter(x => x.length == 2).map(x => (x(0),x(1)))
// reading file and creating the map Example - key 0 value 1,2,4

//from the first map, trying to create pairs
var mapAgainstValue = mapOperation.map{
line =>
val fromFriend = line._1
val toFriendsList = line._2.split(",")
(fromFriend -> toFriendsList)
}

val newMap = mapAgainstValue.map{
line =>
var key ="";
for(userIds <- line._2){
key =line._1.concat(","+userIds);
(key -> line._2.toList)
}

}

问题是我无法在 newMap 上调用 groupByKey。我假设我创建地图的方式存在一些问题?

感谢任何帮助。

谢谢。

【问题讨论】:

  • 请编辑问题并添加更多细节,因为我无法弄清楚您真正想要什么
  • 我编辑了这个问题。希望它比以前更好。

标签: scala apache-spark


【解决方案1】:

你的问题可以这样解决:

 val inputRDD=sc.textFile("inputFile.txt")  
inputRDD.flatMap{a=>
          val list=a.split("--")
          val firstTerm=list(0)
          val secondTermAsList=list(1).split(",")
          secondTermAsList.map{b=>
          val key=if(b>firstTerm) (firstTerm,b) else (b,firstTerm)
          val value=secondTermAsList diff List(b)
          (key,value)
          }
          }

此代码导致此输出:

+-----+------+
|_1   |_2    |
+-----+------+
|[0,1]|[2, 4]|
|[0,2]|[1, 4]|
|[0,4]|[1, 2]|
|[0,1]|[4]   |
|[1,4]|[0]   |
|[0,2]|[4]   |
|[2,4]|[0]   |
|[2,4]|[1, 0]|
|[1,4]|[2, 0]|
|[0,4]|[2, 1]|
+-----+------+

我希望这能解决您的问题!

【讨论】:

  • 那是一段非常好的代码。非常感谢。所以,从这里我应该能够按键分组并与值集相交。
  • 还有一件事,如果不是数据集中的每个元素在分隔符之后都有值,我应该在哪里添加过滤器 -- ?
  • 检查分离后的列表大小是否为 1 。如果只是给出默认值,否则进行计算
  • 我无法添加这样的 if 条件 - val x = inputRDD.flatMap { a => val list = a.split("\t") if (list.length > 1) { val firstTerm = list(0) val secondTermAsList = list(1).split(",") secondTermAsList.map { b => val key = if (b.toInt > firstTerm.toInt) (firstTerm, b) else (b, firstTerm) val value = secondTermAsList diff List(b) (key, value) } } }
  • 您必须将 if 作为表达式进行评估
猜你喜欢
  • 2019-04-26
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 2018-10-10
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 2018-09-17
相关资源
最近更新 更多