Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 在Spark上创建复合关键点_Apache Spark_Pyspark_Rdd - Fatal编程技术网

Apache spark 在Spark上创建复合关键点

Apache spark 在Spark上创建复合关键点,apache-spark,pyspark,rdd,Apache Spark,Pyspark,Rdd,我正在Spark上开发一个基本的协同过滤算法,但我在RDD转换问题上遇到了麻烦。我的输入RDD如下所示: “约翰”,“a”,“5”,“约翰”,“b”,“3”,“约翰”,“c”,“2”,“马克”,“a”,“3”,“马克”,“b”,“4”,“露西”,“b”,“2”,“露西”,“c”,“5”] 在每个RDD元素中,第一个值是用户,第二个值是产品名称(“a”、“b”或“c”),第三个值是其评级 我想通过按名称分组,然后按产品组合来转换输入RDD,这样我的最终结果RDD将是 [(“a”,“b”),(“5”

我正在Spark上开发一个基本的协同过滤算法,但我在RDD转换问题上遇到了麻烦。我的输入RDD如下所示:

“约翰”,“a”,“5”,“约翰”,“b”,“3”,“约翰”,“c”,“2”,“马克”,“a”,“3”,“马克”,“b”,“4”,“露西”,“b”,“2”,“露西”,“c”,“5”]

在每个RDD元素中,第一个值是用户,第二个值是产品名称(“a”、“b”或“c”),第三个值是其评级

我想通过按名称分组,然后按产品组合来转换输入RDD,这样我的最终结果RDD将是

[(“a”,“b”),(“5”,“2”)][(“a”,“b”),(“3”,“4”)][(“a”,“c”),(“5”,“2”)]


在上面的结果中,因为John和Mark对a和b都有“评级”,所以我有两个RDD元素,其中(a,b)是键,它们的评级是值。只有John对a和c都有评级,因此我只有一个RDD元素,其中(a,c)是键。

您可以执行以下操作:

val keyedElems = rdd1.map { case (a, b, c) => (a, (b, c)) }
val groupedCombinations = keyedElems.groupByKey().flatMapValues(_.toList.combinations(2))
val productScoreCombinations = groupedCombinations.mapValues { case (elems: List[(String, String)]) => ((elems(0)._1, elems(1)._1), (elems(0)._2, elems(1)._2)) }.values   
scala> val rdd1 = sc.parallelize(Array(("John", "a", "5"),("John", "b", "3"),("John", "c", "2"),("Mark", "a", "3"),("Mark", "b", "4"),("Lucy", "b", "2"),("Lucy", "c", "5")))
rdd1: org.apache.spark.rdd.RDD[(String, String, String)] = ParallelCollectionRDD[0] at parallelize at <console>:21

scala> val rdd2 = rdd1.map { case (a, b, c) => (a, (b, c)) }
rdd2: org.apache.spark.rdd.RDD[(String, (String, String))] = MapPartitionsRDD[1] at map at <console>:23

scala> val rdd3 = rdd2.groupByKey().flatMapValues(_.toList.combinations(2))
rdd3: org.apache.spark.rdd.RDD[(String, List[(String, String)])] = MapPartitionsRDD[3] at flatMapValues at <console>:25

scala> val rdd4 = rdd3.mapValues { case (elems: List[(String, String)]) => ((elems(0)._1, elems(1)._1), (elems(0)._2, elems(1)._2)) }.values
rdd4: org.apache.spark.rdd.RDD[((String, String), (String, String))] = MapPartitionsRDD[7] at values at <console>:27

scala> rdd4.foreach(println)
...
((a,b),(3,4))
((b,c),(2,5))
((a,b),(5,3))
((a,c),(5,2))
((b,c),(3,2))
我们在这里所做的是按用户键入输入数据集,通过按键分组生成(产品、评级)的iterable列表,生成每个列表的2个组合,将该列表展平以将每个组合放入其自己的记录中,最后重新排序元素,使产品和评级位于其自己的元组中

在Spark中本地运行时,我看到以下情况:

val keyedElems = rdd1.map { case (a, b, c) => (a, (b, c)) }
val groupedCombinations = keyedElems.groupByKey().flatMapValues(_.toList.combinations(2))
val productScoreCombinations = groupedCombinations.mapValues { case (elems: List[(String, String)]) => ((elems(0)._1, elems(1)._1), (elems(0)._2, elems(1)._2)) }.values   
scala> val rdd1 = sc.parallelize(Array(("John", "a", "5"),("John", "b", "3"),("John", "c", "2"),("Mark", "a", "3"),("Mark", "b", "4"),("Lucy", "b", "2"),("Lucy", "c", "5")))
rdd1: org.apache.spark.rdd.RDD[(String, String, String)] = ParallelCollectionRDD[0] at parallelize at <console>:21

scala> val rdd2 = rdd1.map { case (a, b, c) => (a, (b, c)) }
rdd2: org.apache.spark.rdd.RDD[(String, (String, String))] = MapPartitionsRDD[1] at map at <console>:23

scala> val rdd3 = rdd2.groupByKey().flatMapValues(_.toList.combinations(2))
rdd3: org.apache.spark.rdd.RDD[(String, List[(String, String)])] = MapPartitionsRDD[3] at flatMapValues at <console>:25

scala> val rdd4 = rdd3.mapValues { case (elems: List[(String, String)]) => ((elems(0)._1, elems(1)._1), (elems(0)._2, elems(1)._2)) }.values
rdd4: org.apache.spark.rdd.RDD[((String, String), (String, String))] = MapPartitionsRDD[7] at values at <console>:27

scala> rdd4.foreach(println)
...
((a,b),(3,4))
((b,c),(2,5))
((a,b),(5,3))
((a,c),(5,2))
((b,c),(3,2))
运行上述代码时,我在pyspark中看到以下内容:

>>> input = sc.parallelize([("John", "a", "5"),("John", "b", "3"),("John", "c", "2"),("Mark", "a", "3"),("Mark", "b", "4"),("Lucy", "b", "2"),("Lucy", "c", "5")])
...
>>> productScoreCombinations.take(6)
...
[(('b', 'c'), ('2', '5')), (('a', 'b'), ('5', '3')), (('a', 'c'), ('5', '2')), (('b', 'c'), ('3', '2')), (('a', 'b'), ('3', '4'))]

“如果我输入‘a’”这个短语让我有点困惑。你能详细说明一下吗,或者发一些代码吗?很抱歉给你带来困惑。这一刻并不重要,我删除了那一行,这仍然不清楚…分享你到目前为止所做的!我试图找到一个模式,但解释太肤浅了,谢谢。我用的是pyspark,所以我想知道你的想法。有一个问题,rdd.groupByKey()和flatMapValues()是否会给出相同的rdd?据我所知,您是将用户分组在一起,然后找到该用户拥有的所有产品组合。输出产品组合为关键,其各自的评级为关键?是这样吗?@SYZ对于您的第一个问题,如果identity函数被传递到
flatMapValues()
,那么是的。但是,这里我们要传递一个函数,该函数将创建并生成分组元组的组合。关于你的第二个问题,如果你的意思是“各自的评级为价值”,那么你基本上是对的。非常感谢你