映射缩小问题,按值计算

时间:2019-03-13 10:45:10

标签: apache-spark hadoop mapreduce

我是新来的地图简化范例,并试图为以下问题找到更好的解决方案。

我有以下一组行-包含Google Play商店应用评论,列为AppName,类别,类型,评分,示例行可以为[Zomato,Food,Free,4.2],[Swiggy,Food,Pay, 3.2]等 问题,找到每个类别的平均已付评级与免费评级之间的比率吗? 我如何使用map reduce范式/ spark来解决这个问题

就像在地图端发出键和复合值一样(Food,(Free,4.2)),(Food,(Paid,3.2)) 然后用列表(值)在化简侧进行平均计算?有没有更好的办法?

1 个答案:

答案 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"),这样会更有效。