RDD转换为Spark

时间:2016-06-16 07:33:24

标签: matrix apache-spark pyspark rdd

我有下一个RDD,看起来像:

((0,1), 2)
((0,2), 3)
((1,1), 3)

我目前正在寻找一种方法,它将给定的RDD转换为以下形式:

([0, 2, 3],
 [0, 3, 0])

换句话说,该方法根据初始RDD中的键值创建列表的RDD。如果某些值不可用,则方法只在此处放置0。

我自己编写了接下来的两个方法,我将其用于可执行解决方案。

def matrixForm(rdd):
        rdd2 = rdd.map(lambda ((x,y),k): (x,y,k))
        rdd3 = rdd2.map(lambda (i,j,e): (j, (i,e))).groupByKey().sortByKey()
        rdd4 = rdd3.map(lambda (i, x): sorted(list(x), cmp=lambda (i1,e1),(i2,e2) : cmp(i1, i2)))
        rdd5 = rdd4.map(lambda x: map(lambda (i, y): y , x))
        rdd6 = rdd5.map(lambda x: list(x))
        rdd7 = rddTranspose(rdd6)
        return rdd7

def rddTranspose(rdd):
        rddT1 = rdd.zipWithIndex().flatMap(lambda (x,i): [(i,j,e) for (j,e) in enumerate(x)])
        rddT2 = rddT1.map(lambda (i,j,e): (j, (i,e))).groupByKey().sortByKey()
        rddT3 = rddT2.map(lambda (i, x): sorted(list(x), cmp=lambda (i1,e1),(i2,e2) : cmp(i1, i2)))
        rddT4 = rddT3.map(lambda x: map(lambda (i, y): y , x))
        return rddT4.map(lambda x: list(x))

这种方式有效,但似乎效率不高。如果有人有时间并希望讨论并改进我的解决方案,请参与讨论。提前谢谢。

PS输入和输出的第二个例子

((0,0), 1)
((1,1), 1)
((2,2), 1)
((3,3), 1)

([1,0,0,0]
 [0,1,0,0]
 [0,0,1,0]
 [0,0,0,1])

id1的最高索引是多个列表,id2的最高索引是每个唯一列表的长度

1 个答案:

答案 0 :(得分:1)

试试这个:

def toRow(n, lst):
    row = [0] * n
    for (index, val) in lst:
        row[index] = val
    return row

def toDense(rdd):
    n = rdd.map(lambda ((i, j), k): j).max() + 1
    rdd1 = rdd.map(lambda ((i,j), k): (i, (j,k)))
    rdd2 = rdd1.groupByKey().sortByKey().map(lambda x: list(x[1]))
    return rdd2.map(lambda lst: toRow(n, lst))

然后看看:

toDense(rdd).take(2)