Apache spark Spark分组和自定义聚合
我有如下数据Apache spark Spark分组和自定义聚合,apache-spark,apache-spark-sql,apache-spark-1.4,Apache Spark,Apache Spark Sql,Apache Spark 1.4,我有如下数据 n1 d1 un1 mt1 1 n1 d1 un1 mt2 2 n1 d1 un1 mt3 3 n1 d1 un1 mt4 4 n1 d2 un1 mt1 3 n1 d2 un1 mt3 3 n1 d2 un1 mt4 4 n1 d2 un1 mt5 6 n1 d2 un1 mt2 3 我想得到如下输出 n1 d1 un1 0.75 n1 d2 un1 1.5 i、 e在第1列、第2列和第3列进行分组,对于第4列,遵循以下公式, 第四列=组内
n1 d1 un1 mt1 1
n1 d1 un1 mt2 2
n1 d1 un1 mt3 3
n1 d1 un1 mt4 4
n1 d2 un1 mt1 3
n1 d2 un1 mt3 3
n1 d2 un1 mt4 4
n1 d2 un1 mt5 6
n1 d2 un1 mt2 3
我想得到如下输出
n1 d1 un1 0.75
n1 d2 un1 1.5
i、 e在第1列、第2列和第3列进行分组,对于第4列,遵循以下公式,
第四列=组内,mt1+mt2/mt4
我正试图用Spark DF做同样的事情
假设数据位于数据帧a中,列名称为n、d、un、mt、r
我正在尝试这个
sqlContext.udf.registeraggUDF,v:Listmt,r=>?
val b=a.groupByn,d,un.aggcallUdfaggUDF,Listmt,r应该在这里
目前Spark 1.4不支持自定义聚合函数。但是,您可以使用Hive UDAFs。您可以在Spark中看到配置单元用户定义聚合函数UDAF的示例。目前Spark 1.4不支持自定义聚合函数。但是,您可以使用Hive UDAFs。您可以在Spark中看到配置单元用户定义的聚合函数UDAF的示例。如果我理解正确,您首先要计算mt1和mt2行的总和,然后除以mt4中每个不同n1、d1和un1行的总和 虽然可以像上面回答的那样使用自定义聚合函数,但您也可以使用一些蛮力,我将在pyspark中演示,但您应该能够轻松地转换为scala 假设您的原始数据帧名为df,列的顺序为:n、d、un、mt、r 首先为mt1、mt2和mt4中的每一个创建一个新列,如下所示:
from pyspark.sql import functions as F
newdf = df.withColumn("mt1", when(df.mt == "mt1", df.r).otherwise(0).alias("mt1"))
newdf = newdf .withColumn("mt2", when(newdf.mt == "mt2", newdf .r).otherwise(0).alias("mt2"))
newdf = newdf .withColumn("mt4", when(newdf.mt == "mt4", newdf .r).otherwise(0).alias("mt4"))
现在对前3个值进行分组,并将新的3个值相加
aggregated = newdf.groupBy(["n","d","n"]).agg(F.sum(newdf.mt1).alias("sum_mt1"),F.sum(newdf.mt2).alias("sum_mt2"), F.sum(newdf.mt4).alias("sum_mt4"))
现在只需进行计算:
final = aggregated.withColumn("res", (aggregated.sum_mt1 + aggregated.sum_mt2) / aggregated.sum_mt4)
这不是最优雅的解决方案,但它可能适合您…如果我理解正确,您首先要计算mt1和mt2行的总和,然后除以mt4中每个不同n1、d1和un1行的总和 虽然可以像上面回答的那样使用自定义聚合函数,但您也可以使用一些蛮力,我将在pyspark中演示,但您应该能够轻松地转换为scala 假设您的原始数据帧名为df,列的顺序为:n、d、un、mt、r 首先为mt1、mt2和mt4中的每一个创建一个新列,如下所示:
from pyspark.sql import functions as F
newdf = df.withColumn("mt1", when(df.mt == "mt1", df.r).otherwise(0).alias("mt1"))
newdf = newdf .withColumn("mt2", when(newdf.mt == "mt2", newdf .r).otherwise(0).alias("mt2"))
newdf = newdf .withColumn("mt4", when(newdf.mt == "mt4", newdf .r).otherwise(0).alias("mt4"))
现在对前3个值进行分组,并将新的3个值相加
aggregated = newdf.groupBy(["n","d","n"]).agg(F.sum(newdf.mt1).alias("sum_mt1"),F.sum(newdf.mt2).alias("sum_mt2"), F.sum(newdf.mt4).alias("sum_mt4"))
现在只需进行计算:
final = aggregated.withColumn("res", (aggregated.sum_mt1 + aggregated.sum_mt2) / aggregated.sum_mt4)
不是最优雅的解决方案,但它可能适合您…的可能重复