【发布时间】:2016-06-16 18:37:34
【问题描述】:
我有下一个 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 的最高索引是每个唯一列表的长度
【问题讨论】:
-
让我稍微澄清一下你的问题。你有一个
RDD[((id1, id2), value)]形式的rdd。您想将其转换为RDD[list(id1, id2, value)]的形式。但是,rdd 中的某些条目没有值。也就是说,rdd 中存在一个如下所示的元素:((someId1, someId2), " ")。对吗? -
是的,但列表应该只有值(没有键)。例如,我有第一个 id1 两次 0 并且相关的 id2 是一次 1 和另一个时间 2(请参阅我的示例)。我想按 id2:
[((0,0), 0), ((0,1), 2), ((0,2), 3)] -> [0,2,3]的顺序创建 id1 = 0 的所有值的列表作为 python 列表。对于我初始 RDD 中的每个索引对。对我来说,关键是列表中的位置 -
你能举一个例子,初始 rdd 有更多的条目和预期的 rdd 输出吗?
-
这是上面的第一个例子。我最初的 RDD 有 3 行键和值。我想根据键值创建两个列表。也就是说,id1的不同值的个数等于新RDD中列表的个数,第二个id2是该值在列表中的位置。
-
我明白了。您想从稀疏矩阵表示中创建一个密集矩阵。
标签: matrix apache-spark pyspark rdd