将 RDD 转换为键值对 RDD,值在列表中
Convert an RDD into a key value pair RDD, with the values being in a List
我有一个 pairRDD,其元组采用以下形式:
[(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)
));
请注意,此操作将引入随机播放。
显而易见,extractKey
和 extractTuples
是根据需要提取原始元组部分的方法。
由于我对 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
的元数(元素数量),那么在 scala 术语中,它是 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);
}));
我希望一切顺利...上面的代码是 untested/uncompiled...因此,如果您可以通过更正使其正常工作,那么请随时在此答案中应用更正.. .
您可以尝试使用映射函数,例如在 Scala 中:
rdd.map { case (k,v1,v2,v3,v4) => (k,(v1,v2,v3,v4)) }
或 rdd.groupBy 也可以使用,但这在大型数据集上可能效率低下。
我有一个 pairRDD,其元组采用以下形式:
[(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)
));
请注意,此操作将引入随机播放。
显而易见,extractKey
和 extractTuples
是根据需要提取原始元组部分的方法。
由于我对 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
的元数(元素数量),那么在 scala 术语中,它是 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);
}));
我希望一切顺利...上面的代码是 untested/uncompiled...因此,如果您可以通过更正使其正常工作,那么请随时在此答案中应用更正.. .
您可以尝试使用映射函数,例如在 Scala 中:
rdd.map { case (k,v1,v2,v3,v4) => (k,(v1,v2,v3,v4)) }
或 rdd.groupBy 也可以使用,但这在大型数据集上可能效率低下。