Apache spark spark中的自定义累加器类
我想在pyspark中定义一个类型为Apache spark spark中的自定义累加器类,apache-spark,pyspark,Apache Spark,Pyspark,我想在pyspark中定义一个类型为List的累加器,并为工作节点累加字符串值。以下是我的代码: class ListParam(AccumulatorParam): def zero(self, v): return [] def addInPlace(self, acc1, acc2): acc1.extend(acc2) return acc1 然后我定义了一个这种类型的累加器,如下所示 accu = sc.accumulator([], ListParam(
List
的累加器,并为工作节点累加字符串值。以下是我的代码:
class ListParam(AccumulatorParam):
def zero(self, v):
return []
def addInPlace(self, acc1, acc2):
acc1.extend(acc2)
return acc1
然后我定义了一个这种类型的累加器,如下所示
accu = sc.accumulator([], ListParam())
然后在executors中添加不同的值,如下所示
accu.add("abc")
class VectorAccumulatorParam(AccumulatorParam):
def zero(self, value):
return [0.0] * len(value)
def addInPlace(self, val1, val2):
for i in range(len(val1)):
val1[i] += val2[i]
return val1
我希望值abc
在累加器中仅显示为一个值,但累加器添加了三个不同的值(一个pr字符),当我查看驱动程序中的accu
值时,它看起来像['a','b','c']
。如何更改它,使其不会将每个字符作为单独的条目添加到累加器中
--------------编辑----------------
我为累加器定义了另一个自定义类,如下所示
accu.add("abc")
class VectorAccumulatorParam(AccumulatorParam):
def zero(self, value):
return [0.0] * len(value)
def addInPlace(self, val1, val2):
for i in range(len(val1)):
val1[i] += val2[i]
return val1
在worker中,我有以下代码
global accu
accu += [accuracy]
但是当我在驱动程序中打印
accu
时,它是空的。有什么问题吗?您是否试图明确告诉spark执行有关蓄能器的操作?您应该知道,很多时候您需要调用rdd.collect()来实际执行映射您是否尝试显式地告诉spark执行处理累加器的操作?您应该知道,很多时候您需要调用rdd.collect()来实际执行映射我遇到了与您相同的问题,看到了这个问题并处理了您的代码。下面的代码运行在带有(Py)Spark 2的HDP2.5集群上,对我有用
我接受了你的类并将其更改为附加字符串
from pyspark.accumulators import AccumulatorParam
class ListParam(AccumulatorParam):
def zero(self, v):
return []
def addInPlace(self, variable, value):
variable.append(value)
return variable
然后我创建了一个累加器变量和一个测试数据帧:
accu = sc.accumulator([], ListParam())
rdd = sc.parallelize([(0,1), (0,1), (0,2), (1,2), (1,10), (1,20), (3,18), (3,18), (3,18)])
df=rdd.toDF(['id','score'])
对于我正在开发的程序,我必须将数据帧重新划分为单个大小。所以我也试过这个:
df.repartition(2)
之后,我创建了一个worker函数,它将向累加器列表追加一个字符串:
def worker(row):
global accu
accu.add("Moin")
现在我可以调用datafame的foreach循环(每个分区都是一个任务):
每个任务都会使用自己的字符串列表将一项附加到列表中:
>>> accu
Accumulator<id=66, value=[['Moin', 'Moin', 'Moin', 'Moin'], ['Moin', 'Moin', 'Moin', 'Moin', 'Moin']]>
结果:
>>> res
['Moin', 'Moin', 'Moin', 'Moin', 'Moin', 'Moin', 'Moin', 'Moin', 'Moin']
我和你有同样的问题,看到了这个问题,并使用了你的代码。下面的代码运行在带有(Py)Spark 2的HDP2.5集群上,对我有用 我接受了你的类并将其更改为附加字符串
from pyspark.accumulators import AccumulatorParam
class ListParam(AccumulatorParam):
def zero(self, v):
return []
def addInPlace(self, variable, value):
variable.append(value)
return variable
然后我创建了一个累加器变量和一个测试数据帧:
accu = sc.accumulator([], ListParam())
rdd = sc.parallelize([(0,1), (0,1), (0,2), (1,2), (1,10), (1,20), (3,18), (3,18), (3,18)])
df=rdd.toDF(['id','score'])
对于我正在开发的程序,我必须将数据帧重新划分为单个大小。所以我也试过这个:
df.repartition(2)
之后,我创建了一个worker函数,它将向累加器列表追加一个字符串:
def worker(row):
global accu
accu.add("Moin")
现在我可以调用datafame的foreach循环(每个分区都是一个任务):
每个任务都会使用自己的字符串列表将一项附加到列表中:
>>> accu
Accumulator<id=66, value=[['Moin', 'Moin', 'Moin', 'Moin'], ['Moin', 'Moin', 'Moin', 'Moin', 'Moin']]>
结果:
>>> res
['Moin', 'Moin', 'Moin', 'Moin', 'Moin', 'Moin', 'Moin', 'Moin', 'Moin']