пока цикл на карте искрится - PullRequest
0 голосов
/ 01 мая 2019

У меня есть эта проблема с mapType в искре с использованием scala API для каждого сеанса. Мы отправляем карту, в которой вы можете найти категории посещенных пользователем, связанные с количеством событий в каждой категории

[ home & personal items > interior -> 1, vehicles > cars -> 1] 

Не все пользователи посещают одно и то же количество категорий, поэтому размер карты меняется в зависимости от идентификатора пользователя

Мне нужно рассчитать количество сеансов, сгруппированных по категориям, чтобыМне нужно пройтись по карте, и хотя это не пустые вещи, которые я пробовал раньше

while (size(col("categoriesRaw")) !== 0) {
    df.select(
        explode(col("categoriesRaw"))
    )
    .select(
        col("key").alias("categ"),
        col("value").alias("number_of_events")
    )
}

, но я сталкиваюсь с некоторыми ошибками, такими как:

type mismatch;
 found   : org.apache.spark.sql.Column
 required: Booleansbt

1 Ответ

1 голос
/ 01 мая 2019

Я не уверен, что вы пытаетесь сделать с помощью цикла while. В любом случае, вы можете проверить с помощью REPL, что выражение, которое вы используете в качестве условия, является Column, а не Boolean, следовательно, Исключение.

> size(col("categoriesRaw")) !== 0
res1: org.apache.spark.sql.Column = (NOT (size(categoriesRaw) = 0))

По сути, это выражение, которое должно оцениваться SparkSQL в where, select или любой другой функции, использующей столбцы.

Тем не менее, с вашим искровым кодом вы почти на месте, вам просто нужно добавить groupBy, чтобы получить, где вы хотите. Давайте начнем с создания ваших данных.

import spark.implicits._
val users = Seq( "user 1" -> Map("home & personal items > interior" -> 1,
                                 "vehicles > cars" -> 1), 
                 "user 2" -> Map("vehicles > cars" -> 3)) 
val df = users.toDF("user", "categoriesRaw")

Тогда вам не нужен цикл while для итерации по всем значениям карт. explode делает именно это для вас:

val explodedDf = df.select( explode('categoriesRaw) )
explodedDf.show(false)

+--------------------------------+-----+
|key                             |value|
+--------------------------------+-----+
|home & personal items > interior|1    |        
|vehicles > cars                 |1    |
|vehicles > cars                 |3    |
+--------------------------------+-----+ 

Наконец, вы можете использовать groupBy add, чтобы получить то, что вы хотите.

explodedDf
    .select('key as "categ", 'value as "number_of_events")
    .groupBy("categ")
    .agg(count('*), sum('number_of_events))
    .show(false)

+--------------------------------+--------+---------------------+
|categ                           |count(1)|sum(number_of_events)|
+--------------------------------+--------+---------------------+
|home & personal items > interior|1       |1                    |
|vehicles > cars                 |2       |4                    |
+--------------------------------+--------+---------------------+

NB. Я не был уверен, хотите ли вы сосчитать сеансы (1-й столбец) или события (2-й столбец), поэтому я вычислил оба.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...