如何在spark上优化此代码?

时间:2014-12-04 06:39:59

标签: python apache-spark

如何在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)))

有人会对优雅的编码风格提出一些建议吗? 谢谢!

1 个答案:

答案 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])
    )