我有一个成对的RDD,元组的格式如下:

[(1,"b1","c1","d1","e1"), (2,"b2","c2","d2","e2"), ...


我想要的是将以上内容转换为键-值对RDD,其中第一个字段将为键,第二个字段为字符串(值)列表。即我想将其转换为以下形式:

[(1,["b1","c1","d1","e1"]), (2,["b2","c2","d2","e2"]), ...


之后,是否可以访问我想要的任何字段?

例如,我可以访问元组(1,["b1","c1","d1","e1"]),然后仅提取字段d1吗?

最佳答案

如果您具有带元组的RDD,但是表示了元组,则可以使用mapToPair将元组的RDD转换为键和值为首选的PairRDD。

在Java 8中,这可能是

JavaPairRDD<Integer,List<String>> r =
  rddOfTuples.mapToPair((t)->new Tuple2(
      extractKey(t),
      extractTuples(t)
  ));


请注意,此操作将导致随机播放。

显而易见,extractKeyextractTuples是要根据需要提取原始元组部分的实现方法。

由于我对Scala元组的了解有限,并且假设输入类似scala.Tuple5<String,Integer,Integer,Integer,Integer>,则可能是:

JavaPairRDD<Integer,List<String>> r =
  rddOfTuples.mapToPair((t)->new Tuple2(
      t._1,
      Arrays.asList(t._2,t._3,t._4,t._6)
  ));


但是,如果您事先不知道Tuple的稀疏度(元素数),则按标量表示,它是Product。要动态访问元素,您将需要使用Product界面,并选择以下选项:


int productArity()
Object productElement(int n)
Iterator<Object> productIterator()


然后,它成为常规的Java练习:

JavaPairRDD<Integer,List<String>> r =
  rddOfTuples.mapToPair((t)->{
    List<String> l = new ArrayList<>(t.productArity()-1);
    for (int i = 1; i < t.productArity(); i++) {
      l.set(i-1,t.productElement(i));
    }
    return new Tuple2<>(t._1,l);
  }));


我希望我一切都好...上面的代码未经测试/未经编译...因此,如果您可以将其与更正一起使用,请随时在此答案中应用更正...

08-07 07:08