Я новичок в парадигме сокращения карты и пытаюсь найти лучшее решение для проблемы, указанной ниже.

У меня есть приведенный ниже набор строк, состоящий из обзоров приложений магазина Google Play, столбцы - это имя приложения, категория, тип, рейтинг, пример строки может быть [Zomato, Food, Free, 4.2], [Swiggy, Food, Paid, 3.2] и Итак, вопрос, найдите соотношение между средними платными и бесплатными рейтингами для каждой категории? как я могу решить эту проблему, используя карту сокращения парадигмы / искры

Это как на стороне карты испускать ключ и составное значение как (Food, (Free, 4.2)), (Food, (Paid, 3.2)), а затем выполнять среднее вычисление на стороне уменьшения со списком (значения)? Есть ли способ лучше?

-1
Kalaiselvam M 13 Мар 2019 в 13:45

1 ответ

Лучший ответ

В искре это было бы очень просто. Логика уменьшения карты будет полностью скрыта от вас.

// 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|
+-----+----+----+------------------+

NB: если вы знаете, что этот тип может быть только платным или бесплатным, вы можете использовать .pivot("type", Seq("paid", "free"), что будет более эффективно.

0
Oli 13 Мар 2019 в 13:16