【问题标题】:RDD transform into SparkRDD 转换成 Spark
【发布时间】: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


【解决方案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)

【讨论】:

  • @Guforu,用你拥有的数据集,是否有可能在最终答案中获得[0,0,0,0]?在我的代码中,我没有包含这种情况,但我可以更改代码以反映这一点。
  • 这实际上是不可能的,我想阻止这个选项...再次感谢您,您的解决方案提高了我的时间性能
猜你喜欢
  • 2016-06-23
  • 1970-01-01
  • 1970-01-01
  • 2015-02-10
  • 1970-01-01
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多