我写了一个对分组数据进行标准缩放的类。
class Scaler:
.
.
.
.
def __transformOne__(self, df_with_stats, newName, colName):
return df_with_stats\
.withColumn(newName,
(F.col(colName)-F.col(f'avg({colName})'))/(F.col(f'stddev_samp({colName})')+self.tol))\
.drop(colName)\
.withColumnRenamed(newName, colName)
def transform(self, df):
df_with_stats = df.join(....) #calculate stats here by doing a groupby and then do a join
return reduce(lambda df_with_stats, kv: self.__transformOne__(df_with_stats, *kv),
self.__tempNames__(), df_with_stats)[df.columns]
这个想法是将均值和方差保存在列中,然后简单地对要缩放的列进行列减法/除法。这部分在功能transformOne
中完成。因此,基本上,它是对一列进行算术运算。
如果我想缩放多个列,则只需多次调用函数transformOne
,但使用functools.reduce
会更有效(请参见函数transform
。该类的运行速度足够快单列,但是当我有多列时,会花费太多时间。
我不了解spark的内部原理,所以我是一个完整的新手。有什么办法可以改善多列的计算能力?
答案 0 :(得分:0)
我的解决方案对withColumn
函数进行了很多调用。因此,我通过使用select
而非withColumn
更改了解决方案。两种方法的物理计划存在很大差异。对于我的应用程序,我使用select
从15分钟改进到2分钟。在SO post中对此有更多信息。