Я не уверен, что вы пытаетесь сделать с помощью цикла 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-й столбец), поэтому я вычислил оба.