如何在Spark中提高此代码的效率?
我需要从数据中计算最小值,最大值,计数,平均值
这是我的样本数据
名称购物货币
A Shop001 99.99
A Shop001 87.15
B Shop001 3.99
...
现在我尝试按名称+商店(键)组织我的数据以生成平均值,最小值,最大值,计数
然后通过collect()获得结果。
这是我在spark中的代码,
def tupleDivide(y):
return float(y[0])/y[1]
def smin(a, b):
return min(a, b)
def smax(a, b):
return max(a, b)
raw = sgRDD.map(lambda x: getVar(parserLine(x),list_C+list_N)).cache()
cnt = raw.map(lambda (x,y,z): (x+"_"+y, 1)).countByKey()
sum = raw.map(lambda (x,y,z): (x+"_"+y, z)).reduceByKey(add)
min = raw.map(lambda (x,y,z): (x+"_"+y, z)).reduceByKey(smin)
max = raw.map(lambda (x,y,z): (x+"_"+y, z)).reduceByKey(smax)
raw_cntRDD = sc.parallelize(cnt.items(),3)
raw_mean = sum.join(raw_cntRDD).map(lambda (x, y): (x, tupleDivide(y)))
有人会对优雅的编码风格提出一些建议吗? 谢谢!
答案 0 :(得分:2)
您应该使用aggregateByKey
进行更优化的处理。我们的想法是存储由{count,min,max和sum组成的state
向量,并使用聚合函数来获取最终值。此外,您可以使用元组作为键,不必将键连接成单个字符串。
data = [
['x', 'shop1', 1],
['x', 'shop1', 2],
['x', 'shop2', 3],
['x', 'shop2', 4],
['x', 'shop3', 5],
['y', 'shop4', 6],
['y', 'shop4', 7],
['y', 'shop4', 8]
]
def add(state, x):
state[0] += 1
state[1] = min(state[1], x)
state[2] = max(state[2], x)
state[3] += x
return state
def merge(state1, state2):
state1[0] += state2[0]
state1[1] = min(state1[1], state2[1])
state1[2] = max(state1[2], state2[2])
state1[3] += state2[3]
return state1
res = sc.parallelize(data).map(lambda x: ((x[0], x[1]), x[2])).aggregateByKey([0, 10000, 0, 0], add, merge)
for x in res.collect():
print 'Client "%s" shop "%s" : count %d min %f max %f avg %f' % (
x[0][0], x[0][1],
x[1][0], x[1][1], x[1][2], float(x[1][3])/float(x[1][0])
)