地图上的while循环会触发数据框

时间:2019-05-01 16:28:16

标签: scala apache-spark dataframe

我使用Scala API在Spark中使用 mapType 存在此问题 对于每个会话,我们都会发送一张地图,您可以在其中找到用户访问过的类别以及每个类别中的事件数

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

不是所有的用户都访问相同数量的类别,因此地图的大小根据user_id改变

我需要计算按类别分组的会话数 为了做到这一点,我需要遍历地图,虽然它不是空的 我以前尝试过的东西

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 个答案:

答案 0 :(得分:1)

我不确定您要使用while循环做什么。无论如何,您可以使用REPL来检查用作条件的表达式是Column而不是Boolean,因此是异常。

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

基本上,这是需要由SparkSQL在whereselect或任何其他使用Columns的函数中求值的表达式。

尽管如此,有了您的Spark代码,您已经快要在那里了,您只需要添加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添加获取所需的内容。

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:我不确定您是要计算会话(第一列)还是事件(第二列),所以我将两者都计算了。