我是新来的地图简化范例,并试图为以下问题找到更好的解决方案。
我有以下一组行-包含Google Play商店应用评论,列为AppName,类别,类型,评分,示例行可以为[Zomato,Food,Free,4.2],[Swiggy,Food,Pay, 3.2]等 问题,找到每个类别的平均已付评级与免费评级之间的比率吗? 我如何使用map reduce范式/ spark来解决这个问题
就像在地图端发出键和复合值一样(Food,(Free,4.2)),(Food,(Paid,3.2)) 然后用列表(值)在化简侧进行平均计算?有没有更好的办法?
答案 0 :(得分:0)
在火花中,这将非常简单。地图归约逻辑将对您完全隐藏。
// let's define some data
val df = Seq((0, "cat_a", "free", 2.5), (1, "cat_a", "free", 3.5), (2, "cat_a", "paid", 4.1),
(3, "cat_a", "paid", 4.5), (4, "cat_b", "free", 2.5), (5, "cat_b", "paid", 4.8))
.toDF("app", "cat", "type", "rating")
df.show
+---+-----+----+------+
|app| cat|type|rating|
+---+-----+----+------+
| 0|cat_a|free| 2.5|
| 1|cat_a|free| 3.5|
| 2|cat_a|paid| 4.1|
| 3|cat_a|paid| 4.5|
| 4|cat_b|free| 2.5|
| 5|cat_b|paid| 4.8|
+---+-----+----+------+
然后就这么简单:
val result = df.groupBy("cat").pivot("type")
.agg(avg('rating))
.withColumn("ratio", 'free / 'paid)
result.show
+-----+----+----+------------------+
| cat|free|paid| ratio|
+-----+----+----+------------------+
|cat_b| 2.5| 4.8|0.5208333333333334|
|cat_a| 3.0| 4.3|0.6976744186046512|
+-----+----+----+------------------+
注意:如果您知道该类型只能付费或免费,则可以使用.pivot("type", Seq("paid", "free")
,这样会更有效。