您好我正在学习Spark和Scala我有一个场景我需要提出Sparkscala代码
输入文件
Name attr1 attr2 attr3
John Y N N
Smith N Y N
预期产出
John attr1 Y
John attr2 N
John attr3 N
Smith attr1 N
...
...
我知道如何在Map-Reduce中执行此操作
对于每一行,单独获取Name并迭代attr值并将输出发送为(Name, attrX Y/N)
,但在scala和Spark中它有点令人困惑,任何人都可以帮助我吗?
答案 0 :(得分:2)
假设您已经知道输入属性的数量,并且输入属性由\t
分隔,那么您可以这样做:
在Java中
// load data file
JavaRDD<String> file = jsc.textFile(path);
// build header rdd
JavaRDD<String> header = jsc.parallelize(Arrays.asList(file.first()));
// subtract header to have real data
JavaRDD<String> data = file.subtract(header);
// create row rdd
JavaRDD<Row> rowRDD = data.flatMap(new FlatMapFunction<String,Row>(){
private static final long serialVersionUID = 1L;
@Override
public Iterable<Row> call(String line) throws Exception {
String[] strs = line.split("\t");
Row r1 = RowFactory.create(strs[0], "Attr1", strs[1]);
Row r2 = RowFactory.create(strs[0], "Attr2", strs[2]);
Row r3 = RowFactory.create(strs[0], "Attr3", strs[3]);
return Arrays.asList(r1,r2,r3);
}
});
// schema for df
StructType schema = new StructType().add("Name", DataTypes.StringType)
.add("Attr", DataTypes.StringType)
.add("Value", DataTypes.StringType);
DataFrame df = sqlContext.createDataFrame(rowRDD, schema);
df.show();
以下是输出:
+-----+-----+-----+
| Name| Attr|Value|
+-----+-----+-----+
|Smith|Attr1| N|
|Smith|Attr2| Y|
|Smith|Attr3| N|
| John|Attr1| Y|
| John|Attr2| N|
| John|Attr3| N|
+-----+-----+-----+
Scala和Java类似,您可以轻松地将它们转换为Scala。