如果我们有一个Pandas数据框,其中包含一个类别列和一个值列,我们可以通过执行以下操作来删除每个类别中的平均值:
我尝试使用分组/连接来实现,如下所示:
df["DemeanedValues"] = df.groupby("Category")["Values"].transform(lambda g: g - numpy.mean(g))
据我所知,Spark数据框架直接不提供这种分组/转换操作(我正在使用Spark 1.5.0上的PySpark)。那么,最好的实现方法是什么?我尝试使用分组/连接来实现,如下所示:
df2 = df.groupBy("Category").mean("Values")
df3 = df2.join(df)
但是,据我理解,每个类别需要对DataFrame进行完整扫描,因此速度非常慢。
我认为(但没有验证),如果我将group-by/mean的结果收集到一个字典中,然后在UDF中使用该字典,可以大大加快速度:
nameToMean = {...}
f = lambda category, value: value - nameToMean[category]
categoryDemeaned = pyspark.sql.functions.udf(f, pyspark.sql.types.DoubleType())
df = df.withColumn("DemeanedValue", categoryDemeaned(df.Category, df.Value))
有没有一种惯用的方式来表达这种操作而不牺牲性能?
df.explain(extended=True)
)是非常有用的。忽略配置的最常见问题与笛卡尔积相关,即使提供了连接表达式也可能无法优化。 - zero323