我正在尝试使用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列表有助于减少内存使用量吗?答案 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 ...,最好不要将其投入生产:)
目前,我最大的客户已经融入了合理的记忆。我在一个非常并行的低内存执行程序工作中处理我的大多数客户端,而在一个不那么并行的高内存执行程序工作中处理最大的客户端。我决定根据我执行的预先计算