Spark数据帧groupBy并进一步计算聚合

时间:2018-03-24 14:08:31

标签: scala apache-spark dataframe aggregation

Dataframe示例:

col_1, col_2
aaa, 1
aaa, 0
bbb, 1
bbb, 1
bbb, 1 

我希望得到一个包含3列的df:col_1,行的总计数,以及col_2 === 1的行数。

我试过

df.groupBy($"col_1")
   .agg(count($"col_2" === 1).as("delayed"), count(lit(1)) as "total").show(100)  

为什么总计算正确,但延迟不计算?

2 个答案:

答案 0 :(得分:0)

$"col2"===1仍然具有与$"col2"相同数量的元素,它们只是truefalse。相反,您想要转换为整数和总和。 (当然,如果col2的值总是1或0,你可以直接求和。)

我认为你必须定义一个udf来将布尔值转换为整数:

val toInt = udf((x: Boolean) => if(x) 1 else 0)

然后(我没有命名我的专栏):

scala> df.groupBy($"_1").agg(sum(toInt($"_2"===1)), count($"_2")).show()
+---+------------------+---------+
| _1|sum(UDF((_2 = 1)))|count(_2)|
+---+------------------+---------+
|aaa|                 1|        2|
|bbb|                 3|        3|
+---+------------------+---------+

答案 1 :(得分:0)

<强>问题

使用count($"col_2" === 1).as("delayed")

引用count function

  
    

public static Column count(Column e) Aggregate function: returns the number of items in a group. Parameters: e - (undocumented) Returns: (undocumented) Since: 1.3.0

  

而不是scala count function

  
    

def count(p : (A) => Boolean) : Int Count the number of elements in the list which satisfy a predicate. Parameters p - the predicate for which to count Returns the number of elements satisfying the predicate p.

  

因此,count($"col_2" === 1) $"col_2" === 1内的条件不会被视为 true false ,而是作为列。因此,count函数只计算列$"col_2" === 1

我希望解释清楚易懂。

解决方案

您应该使用when函数将值更改为1或0 sum函数用作计数

sum(when($"col_2" === 1, 1).otherwise(0)).as("delayed")

如果c ol_2列始终 0或1 ,那么您只能使用sum

sum($"col_2").as("delayed")