2015-04-28 4 views
2

Можно ли найти медианную в искру распределенным способом? Я в настоящее время находят: Sum, Average, Variance, Count используя следующий код:pySpark найти медиану распределенным способом?

dataSumsRdd = numRDD.filter(lambda x: filterNum(x[1])).map(lambda line: (line[0], float(line[1])))\ 
    .aggregateByKey((0.0, 0.0, 0.0), 
    lambda (sum, sum2, count), value: (sum + value, sum2 + value**2, count+1.0), 
    lambda (suma, sum2a, counta), (sumb, sum2b, countb): (suma + sumb, sum2a + sum2b, counta + countb)) 
#Generate RDD of Count, Sum, Average, Variance 
dataStatsRdd = dataSumsRdd.mapValues(lambda (sum, sum2, count) : (count, sum, sum/count, round(sum2/count - (sum/count)**2, 7))) 

Я не совсем уверен, как найти Медиана хотя. Чтобы найти стандартное отклонение, я просто делаю результат локально с квадратичной дисперсией. Как только я соберу медиана, я могу, чем легко сделать Skewness на местном уровне.

У меня есть данные в пар/значение (ключ = столбец)

+1

Посмотрите на [этот вопрос] (http://stackoverflow.com/questions/28158729/how-can-i-calculate-exact-median-with-apache-spark). Эффективный распределенный медианный алгоритм не является простым. – nrg

ответ

1

что я смотрю на это (его не лучшим образом ... но единственный способ, которым я могу думать это делать):

def medianFunction(x): 
    count = len(x) 
    if count % 2 == 0: 
     l = count/2 - 1 
     r = l + 1 
     value = (x[l - 1] + x[r - 1])/2 
     return value 
    else: 
     l = count/2 
     value = x[l - 1] 
     return value 

    medianRDD = numFilterRDD.groupByKey().map(lambda (x, y): (x, list(y))).mapValues(lambda x: medianFunction(x)).collect() 
+0

Линия medianRDD = заканчивается на .collect(). Это намеренно? Вы тестировали это решение на небольшом тестовом материале? –

+0

.collect - это действие, и это делает что-то, что даст результат, который не опасен для водителя. В чем вас беспокоит? – theMadKing