如何使用 Spark JavaRDD 将列拆分为多行
How to split column into multiple rows using Spark JavaRDD
正在加载数据:
SparkConf sc= new SparkConf().setAppName("TEST").setMaster("local[*]");
JavaSparkContext JSC = new JavaSparkContext(sc);
JavaRDD<String> stringRDDVotes = JSC.textFile("HarryPotter.csv");
我目前已将此 table 加载到 RDD 中:
ID
A
B
Name
1
23
50
Harry;Potter
我想把它转换成下面的table:
ID
A
B
Name
1
23
50
Harry
1
23
50
Potter
我找到的所有解决方案都使用了我无法使用的 SparkSQL,所以我如何仅使用 flatMap
和 mapToPair
.
之类的东西来获得这个结果
也许是这样的?
flatMap(s -> Arrays.asList(s.split(";")).iterator())
上面的代码产生这个:
ID
A
B
Name
1
23
50
Harry
Potter
我知道在 scala 中可以这样做,但我不知道如何使用 java:
val input: RDD[String] = sc.parallelize(Seq("1,23,50,Harry;Potter"))
val csv: RDD[Array[String]] = input.map(_.split(','))
val result = csv.flatMap { case Array(s1, s2, s3, s4) => s4.split(";").map(part => (s1, s2, s3, part)) }
第一部分从Scala转换为Java非常简单,你只需要使用map
用逗号分隔每行得到一个JavaRDD<String[]>
。然后使用 flatMap
,对于每一行,拆分对应于 Name
的数组的最后部分,并使用 java 流,您可以将 names 列表的每个元素转换为一个新列表。
这是一个完整的例子:
JavaRDD<String> input = JSC.parallelize(
Arrays.asList("1,23,50,Harry;Potter", "2,24,60,Hermione;Granger")
);
JavaRDD<String[]> result = input.map(line -> line.split(","))
.flatMap(r -> {
List<String> names = Arrays.asList(r[3].split(";"));
String[][] values = names.stream()
.map(name -> new String[]{r[0], r[1], r[2], name})
.toArray(String[][]::new);
return Arrays.asList(values).iterator();
});
// print the result RDD
for (String[] line : result.collect()) {
System.out.println(Arrays.toString(line));
}
// [1, 23, 50, Harry]
// [1, 23, 50, Potter]
// [2, 24, 60, Hermione]
// [2, 24, 60, Granger]
正在加载数据:
SparkConf sc= new SparkConf().setAppName("TEST").setMaster("local[*]");
JavaSparkContext JSC = new JavaSparkContext(sc);
JavaRDD<String> stringRDDVotes = JSC.textFile("HarryPotter.csv");
我目前已将此 table 加载到 RDD 中:
ID | A | B | Name |
---|---|---|---|
1 | 23 | 50 | Harry;Potter |
我想把它转换成下面的table:
ID | A | B | Name |
---|---|---|---|
1 | 23 | 50 | Harry |
1 | 23 | 50 | Potter |
我找到的所有解决方案都使用了我无法使用的 SparkSQL,所以我如何仅使用 flatMap
和 mapToPair
.
也许是这样的?
flatMap(s -> Arrays.asList(s.split(";")).iterator())
上面的代码产生这个:
ID | A | B | Name |
---|---|---|---|
1 | 23 | 50 | Harry |
Potter |
我知道在 scala 中可以这样做,但我不知道如何使用 java:
val input: RDD[String] = sc.parallelize(Seq("1,23,50,Harry;Potter"))
val csv: RDD[Array[String]] = input.map(_.split(','))
val result = csv.flatMap { case Array(s1, s2, s3, s4) => s4.split(";").map(part => (s1, s2, s3, part)) }
第一部分从Scala转换为Java非常简单,你只需要使用map
用逗号分隔每行得到一个JavaRDD<String[]>
。然后使用 flatMap
,对于每一行,拆分对应于 Name
的数组的最后部分,并使用 java 流,您可以将 names 列表的每个元素转换为一个新列表。
这是一个完整的例子:
JavaRDD<String> input = JSC.parallelize(
Arrays.asList("1,23,50,Harry;Potter", "2,24,60,Hermione;Granger")
);
JavaRDD<String[]> result = input.map(line -> line.split(","))
.flatMap(r -> {
List<String> names = Arrays.asList(r[3].split(";"));
String[][] values = names.stream()
.map(name -> new String[]{r[0], r[1], r[2], name})
.toArray(String[][]::new);
return Arrays.asList(values).iterator();
});
// print the result RDD
for (String[] line : result.collect()) {
System.out.println(Arrays.toString(line));
}
// [1, 23, 50, Harry]
// [1, 23, 50, Potter]
// [2, 24, 60, Hermione]
// [2, 24, 60, Granger]