将用户定义的函数应用于PySpark数据帧并返回字典

时间:2017-08-25 10:49:01

标签: pandas pyspark spark-dataframe

假设我有一个名为df

的pandas数据帧
id value1 value2
1 2 1
2 2 1
3 4 5

在普通的Python中,我编写了一个函数来处理这个数据帧并返回一个字典:

d = dict()
for row in df.itertuples()
   x = do_something (row)
   d[x[0]] = x[1:]

我正在尝试使用Spark重新实现此功能。

d = dict() # define a global var
def do_something (id, value1, value2):
   # business logic
   d[x0] = [x1,x2,x3]
   return 0
udf_do = udf (do_something)

然后:

df_spark.select (udf_do ('id','value1','value2'))

我的想法是,通过调用df_spark.select,将在数据帧上调用函数do_something,它将更新全局变量d。我并不真正关心udf_do的返回值,所以我返回0。

我的解决方案确实不起作用。

你能否告诉我一些迭代方法(我知道它不是Spark方式)或以某种方式处理Spark数据帧并更新外部字典?

请注意,数据框非常大。我试着通过调用toPandas()将其转换为pandas但我有OOM问题。

1 个答案:

答案 0 :(得分:0)

UDF无法更新任何全局状态。但是,您可以在UDF中进行一些业务登录,然后使用toLocalIterator以内存高效的方式(按分区分区)将所有数据传递给驱动程序。例如:

df = spark.createDataFrame([(10, 'b'), (20, 'b'), (30, 'c'), 
                            (40, 'c'), (50, 'c'), (60, 'a')], ['col1', 'col2'])
df.withColumn('udf_result', ......)
df.cache()
df.count() # force cache fill

for row in df.toLocalIterator():
    print(row)