pyspark reduceByKey每个键只有1个值

时间:2016-11-11 11:02:30

标签: python apache-spark pyspark

从平均每行150个属性的多个csv文件中,我需要在pyspark中满足此SQL请求:

SELECT object_id, COUNT(*), MAX(source_id), MIN(ra), MAX(ra), MIN(decl), MAX(decl)

我使用了一个map函数,它接受每一行,过滤并输出所需的字段:

Map Output : < object_id , Array( objectid , 1,sourceid,ra,decl] ) >

我使用了一个reduce函数,它一次计算所有必需的聚合函数(A和B是数组,如地图输出中所述):

def generalReduce(A,B):
    myarrayRet = [0,0,0,0,0,0,0]
    myarrayRet[0] = A[0]
    #count
    myarrayRet[1] = A[1] + B[1]
    #maxSrcId
    myarrayRet[2] = A[2] if A[2] > B[2] else B[2]
    #minRa
    myarrayRet[3] = A[3] if A[3] < B[3] else B[3]
    #maxRa
    myarrayRet[4] = A[3] if A[3] > B[3] else B[3]
    #minDecl
    myarrayRet[5] = A[4] if A[4] > B[4] else B[4]
    #maxDecl
    myarrayRet[6] = A[4] if A[4] > B[4] else B[4]
    return myarrayRet

问题是,有些键只有1个值,因此reduce阶段输出4个阵列的数组。这让我觉得只有当键的值超过1时才调用reduce函数,我错了吗?如果没有,如果每个键只有一个值,我该如何输出自定义值?

谢谢。

1 个答案:

答案 0 :(得分:1)

我不确定我是否正确理解你的问题。如果你有像data这样的键值RDD,如下所示:

Map Output : < object_id , Array( objectid , 1,sourceid,ra,decl] ) >

使用data.reduceByKey(generalReduce),你的函数generalReduce应该是可交换的和关联的。也就是说,如果您有三个元素,generalReduce(generalReduce(elem1,elem2),elem3)应该等于generalReduce(elem1,generalReduce(elem2,elem3)。在您的代码中,generalReduce(elem1,elem2)的返回值与elem3的类型不同,因此您应该考虑到这一点。事实上,我不认为你的代码正在做你打算做的事情。

对于您的第二个问题,如果您想要这样做,您可以使用地图以正确的格式转换值。