假设我有一个名为df
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问题。
答案 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)