我正在尝试处理LogFile。首先,我按照我的要求读取日志文件并拆分这些文件,并将每个列保存到单独的JavaRDD中。现在我需要将这些JavaRDD转换为DataFrames以供将来操作。这是我到目前为止所尝试的代码:
SparkConf conf = new SparkConf().setAppName("AuctionBid").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> diskfile = sc.textFile("/Users/karuturi/Downloads/log.txt");
JavaRDD<String> urlrdd=diskfile.flatMap(line -> Arrays.asList(line.split("\t")[0]));
System.out.println(urlrdd.take(1));
SQLContext sql = new SQLContext(sc);
这就是我尝试将JavaRDD转换为DataFrame的方式:
DataFrame fileDF = sqlContext.createDataFrame(urlRDD, Model.class);
但是上面这行没有用。我对Model.class感到困惑。
任何人都可以建议我。
感谢。
答案 0 :(得分:16)
<强>进口:强>
import java.io.Serializable;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
为URL创建POJO类。我建议你写日志行,其中包括网址,日期,时间,方法,目标,等等作为成员
public static class Url implements Serializable {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
从文本文件
创建Url对象的RDDJavaRDD<Url> urlsRDD = spark.read()
.textFile("/Users/karuturi/Downloads/log.txt")
.javaRDD()
.map(new Function<String, Url>() {
@Override
public Url call(String line) throws Exception {
String[] parts = line.split("\\t");
Url url = new Url();
url.setValue(parts[0].replaceAll("[", ""));
return url;
}
});
从RDD创建DataFrame
Dataset<Row> urlsDF = spark.createDataFrame(urlsRDD, Url.class);
答案 1 :(得分:5)
你可以做一些事情(我正在从scala转发,所以请原谅任何错别字):
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;
JavaRDD<Row> rowRDD = urlrdd.map(new Function<String, Row>() {
@Override
public Row call(String record) throws Exception {
return RowFactory.create(record());
}
}
// now you wish to create the target schema. This is basically a list of
// fields (each field would be a column) which you are adding to a StructType
List<StructField> fields = new ArrayList<>();
StructField field = DataTypes.createStructField("url", DataTypes.StringType, true);
fields.add(field);
StructType schema = DataTypes.createStructType(fields);
// now you can create the dataframe:
DataFrame df= sqlContext.createDataFrame(rowRDD, schema);
另外几点说明:
当你只拿第一个元素时,为什么要平平?你可以简单地完成:
JavaRDD<String> urlrdd=diskfile.flatMap(line -> line.split("\t")[0]);
我假设在现实生活中你想从网址中删除'['(你可以在地图中轻松完成)。
如果你要转向spark 2.0或更高版本,那么你应该使用spark session(spark)来代替sqlContext。
您可以使用所有列创建单个数据框。您可以通过向架构添加所有字段来实现此目的(即,不是仅仅添加一个字段添加所有字段)。而不是使用urlrdd,使用diskfile并在“公共行调用”创建中进行拆分。这将是这样的:
JavaRDD<Row> rowRDD = diskfile.map(new Function<String, Row>() {
@override public Row call(String record) throws Exception {
String[] recs = record.split("\t")
return RowFactory.create(recs[0], recs[1], ...);
}
});
您可以直接创建:只需使用
sqlContext.read.option("sep","\t").csv.load(filename,schema)
答案 2 :(得分:4)
根据7列表格对您的数据进行平面映射,然后使用下面的代码段
String[] columns = new String[7] {"clumn1","column2","column3","column4","column5","column6","column7"};
List<String> tableColumns = Arrays.asList(columns);
StrucType schema = createSchema(tableColumns);
public StructType createSchema(List<String> tableColumns){
List<StructField> fields = new ArrayList<StructField>();
for(String column : tableColumns){
fields.add(DataTypes.createStructField(column, DataTypes.StringType, true));
}
return DataTypes.createStructType(fields);
}
sqlContext.createDataFrame(urlRDD, schema);
答案 3 :(得分:0)
您可以直接使用sqlContext直接读取文件
使用sqlContext的read方法
有关详情,请点击此链接
https://spark.apache.org/docs/1.6.0/sql-programming-guide.html#creating-dataframes
或者您可以导入
import sqlContext.implicits.*;
然后在rdd上使用toDF()
方法转换为数据帧。