Scala Spark 地图类型匹配问题
Posted
技术标签:
【中文标题】Scala Spark 地图类型匹配问题【英文标题】:Scala Spark map type matching issue 【发布时间】:2016-09-19 21:40:30 【问题描述】:我正在尝试使用 Scala 对日志数据执行一系列转换,但在匹配元组时遇到了困难。我有一个包含用户 ID、网址和日期的数据框。我可以将数据框映射到 RDD 并使用此映射键减少:
val countsRDD = usersUrlsDays.map case Row(date:java.sql.Date, user_id:Long, url:String) => Tuple2(Tuple2(user_id, url), 1) .rdd.reduceByKey(_+_)
这给了我一个 RDD ((user_id, url), count):
scala> countsRDD.take(1)
res9: Array[((Long, String), Int)]
scala> countsRDD.take(1)(0)
res10: ((Long, String), Int)
现在我想通过 url 反转它以产生:
(url, [(user_id, count), ...])
我试过这个:
val urlIndex = countsRDD.map case Row(((user_id:Long, url:String), count:Int)) => Tuple2(url, List(Tuple2(user_id, count))) .reduceByKey(_++_)
然而,这会产生匹配错误:
scala.MatchError: ... (of class scala.Tuple2)
我已经尝试了这两个具有显式和隐式类型的 map 调用的许多不同排列,这似乎让我走得最远。我希望这里有人可以帮助我指出正确的方向。
【问题讨论】:
【参考方案1】:这样的事情应该可以工作:
countsRDD
.map case ((user_id, url), count) => (url, (user_id, count))
.groupByKey
countsRDD
是 RDD[((String, String), Int)]
不是 RDD[Row]
。
无需使用TupleN
。元组文字可以正常工作。
由于countsRDD
是静态类型的(与RDD[Row]
不同),您不必指定类型。
不要使用reduceByKey
进行列表连接。这是您可以采取的最糟糕的方法,并且忽略了计算复杂性、垃圾收集器和常识。 如果您确实需要专为此设计的分组数据使用操作。
【讨论】:
以上是关于Scala Spark 地图类型匹配问题的主要内容,如果未能解决你的问题,请参考以下文章
Scala、Array[Int] 和 Array[Option[Int]] 中的类型不匹配
类型不匹配;找到:org.apache.spark.sql.DataFrame 需要:org.apache.spark.rdd.RDD