在spark / scala中迭代一个巨大的数据框

时间:2017-03-14 18:27:05

标签: scala apache-spark apache-spark-sql spark-dataframe spark-cassandra-connector

我有一个包含5亿行的数据框。我想迭代每一行并修改列名/删除几列,并根据几个条件更新列值。我正在使用以下方法收集。

df.collect.foreach(row => mycustomeMethod())

由于收集会将所有数据带到驱动程序我面临内存错误。您可以建议任何其他方法来实现相同的目标。

我们正在使用datastax的spark-cassandra连接器。我尝试了不同的方法,但没有任何方法有助于提高性能。

1 个答案:

答案 0 :(得分:3)

使用map操作代替collect / foreach,然后转换回RDD。这将允许计算分布在集群周围,而不是将其全部强制转换为一个节点。您可以通过修改自定义方法来获取并返回一行,然后将其转换回DataFrame。

val oldSchema = originalDf.schema
val newSchema = //TODO: put new schema based on what you want to do
val newRdd = originalDf.map(row => myCustomMethod(row))
val newDf = sqlContext.createDataFrame(newRdd,newSchema)

然后可以通过新DataFrame上的.drop方法处理删除行。

如果您的自定义方法不可序列化 - 或者包含不可序列化的对象 - 在这种情况下切换到mapPartitions方法,这可能会遇到问题,这样您就可以强制每个节点先创建相关对象的副本。