(Py)Spark combineByKey mergeCombiners输出类型!= mergeCombinerVal类型

时间:2017-08-01 19:59:58

标签: python pandas apache-spark pyspark

我正在尝试使用Pandas DF优化用Python编写的一个软件。该算法将pandas DF作为输入,不能分发,并为每个客户输出一个度量。

也许它不是最好的解决方案,但我的时间效率方法是并行加载所有文件,然后为每个客户端构建DF

这很好用但很少有客户拥有大量的数据。所以我需要在创建DF时节省内存。

为了做到这一点,我执行了一个groupBy()(实际上是一个combineByKey,但逻辑上它是一个groupBy),然后对于每个组(现在又称为RDD的一行),我构建了一个列表并从中获得一只熊猫DF。

然而,这会在单个任务/节点中生成许多数据副本(RDD行,列表和pandas DF ...)并崩溃,我想在单个节点中删除那么多副本。

我正在思考一个特殊的" combineByKey与以下伪代码:

def createCombiner(val):
    return [val]

def mergeCombinerVal(x,val):
    x.append(val);
    return x;

def mergeCombiners(x,y):
    #Not checking if y is a pandas DF already, but we can do it too
    if (x is a list):
       pandasDF= pd.Dataframe(data=x,columns=myCols);
       pandasDF.append(y);
       return pandasDF
    else:
       x.append(y);
       return x;

我的问题在这里,文档没有说什么,但有人知道是否可以安全地认为这会有用吗? (返回合并两个组合器的数据类型与组合器不同)。如果" bad"的数量,我也可以在mergeCombinerVal上控制数据类型。调用是边缘的,但​​是逐行追加到pandas DF是非常低效的。

有什么更好的想法来表达我想做的事情吗?

谢谢!,

PS:现在我正在打包Spark行,从Spark行切换到没有列名的python列表有助于减少内存使用量吗?

1 个答案:

答案 0 :(得分:1)

只需将我的评论写为答案

最后我使用了常规的combineByKey,它比groupByKey更快(idk的确切原因,我想它有助于打包行,因为我的行很小,但有maaaany行),并且还允许我将他们分成一个真实的" Python List(groupByKey组成某种Iterable,Pandas不支持并迫使我创建另一个结构副本,这会使内存使用和崩溃加倍),这有助于我在将它们打包到Pandas / C时进行内存管理数据类型。

现在我可以使用这些列表直接构建数据框而无需任何额外的转换(我不知道什么结构是Spark的groupByKey" list",但是pandas赢了' t在构造函数中接受它。)

尽管如此,我最初的想法应该会减少一些内存使用量(最多1x DF + 0.5x列表,而现在我有1x DF + 1x列表),但是因为user8371915表示它不能保证API / docs ...,最好不要将其投入生产:)

目前,我最大的客户已经融入了合理的记忆。我在一个非常并行的低内存执行程序工作中处理我的大多数客户端,而在一个不那么并行的高内存执行程序工作中处理最大的客户端。我决定根据我执行的预先计算