我的数据如下,
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,在第1列,第2列和第3列进行分组,第4列按照以下公式进行, 第4列=组内,(mt1 + mt2)/ mt4
我正在尝试使用Spark DF 假设数据在数据帧a中,列名为n,d,un,mt,r 我正在尝试这个。
sqlContext.udf.register("aggUDF",(v:List(mt,r))=> ?)
val b = a.groupBy("n","d","un").agg(callUdf("aggUDF",List((mt,r)) should go here))
答案 0 :(得分:4)
如果我理解正确,你首先要计算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个值的总和。
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)
不是最优雅的解决方案,但它可能适合您...