在一个大的PySpark数据帧的每一行中应用一个函数?

时间:2017-08-25 08:48:06

标签: pyspark large-scale

我有一个大数据帧(~30M行)。我有一个函数ff的业务是遍历每一行,检查一些逻辑并将输出提供给字典。该函数需要逐行执行。

我试过了:

dic = dict() for row in df.rdd.collect(): f(row, dic)

但我总是遇到错误OOM。我将Docker的内存设置为8GB。

我如何有效地开展业务?

非常感谢

2 个答案:

答案 0 :(得分:2)

您可以尝试下面的内容,让我们知道它是否适合您?

from pyspark.sql.functions import udf, struct
from pyspark.sql.types import StringType, MapType

#sample data
df = sc.parallelize([
    ['a', 'b'],
    ['c', 'd'],
    ['e', 'f']
]).toDF(('col1', 'col2'))

#add logic to create dictionary element using rows of the dataframe    
def add_to_dict(l):
    d = {}
    d[l[0]] = l[1]
    return d
add_to_dict_udf = udf(add_to_dict, MapType(StringType(), StringType()))
#struct is used to pass rows of dataframe
df = df.withColumn("dictionary_item", add_to_dict_udf(struct([df[x] for x in df.columns])))
df.show()

#list of dictionary elements
dictionary_list = [i[0] for i in df.select('dictionary_item').collect()]
print dictionary_list

输出是:

[{u'a': u'b'}, {u'c': u'd'}, {u'e': u'f'}]

希望这有帮助!

答案 1 :(得分:1)

使用collect将所有数据从Spark Executors中提取到驱动程序中。你真的应该避免这种情况,因为它使得使用Spark毫无意义(在这种情况下你可以使用普通的python)。

你能做什么: