在Spark java中将JavaRDD转换为数据帧

在Spark java中将JavaRDD转换为数据帧,java,apache-spark,hadoop,apache-spark-sql,Java,Apache Spark,Hadoop,Apache Spark Sql,我正在尝试处理日志文件。首先,我读取日志文件,并根据需要拆分这些文件,并将每个列保存到单独的JavaRDD中。现在,我需要将这些JavaRDD转换为数据帧,以便将来进行操作。这是我到目前为止尝试的代码: SparkConf conf = new SparkConf().setAppName("AuctionBid").setMaster("local"); JavaSparkContext sc = new JavaSparkContext(conf);

我正在尝试处理日志文件。首先,我读取日志文件,并根据需要拆分这些文件,并将每个列保存到单独的JavaRDD中。现在,我需要将这些JavaRDD转换为数据帧,以便将来进行操作。这是我到目前为止尝试的代码:

         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);
但是上面这一行不行。我对Model.class感到困惑

有人能推荐我吗


谢谢

您可以使用sqlContext直接读取文件

使用sqlContext的read方法

有关更多信息,请点击此链接

或者您可以导入

import sqlContext.implicits.*;

然后在rdd上使用
toDF()
方法将其转换为数据帧

只需根据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);
String[]columns=新字符串[7]{“clumn1”、“column2”、“column3”、“column4”、“column5”、“column6”、“column7”};
List tableColumns=Arrays.asList(columns);
structypeschema=createSchema(tableColumns);
公共StructType createSchema(列表表列){
列表字段=新的ArrayList();
对于(字符串列:tableColumns){
add(DataTypes.createStructField(column,DataTypes.StringType,true));
}
返回DataTypes.createStructType(字段);
}
createDataFrame(urlRDD,模式);
您可以执行以下操作(我正在从scala动态转换,请原谅任何打字错误):

import org.apache.spark.sql.Row
导入org.apache.spark.sql.types.DataTypes;
导入org.apache.spark.sql.types.StructField;
导入org.apache.spark.sql.types.StructType;
JavaRDD rowRDD=urlrdd.map(新函数(){
@凌驾
公用行调用(字符串记录)引发异常{
返回RowFactory.create(record());
}
}
//现在您希望创建目标模式
//要添加到StructType的字段(每个字段都是一列)
列表字段=新的ArrayList();
StructField=DataTypes.createStructField(“url”,DataTypes.StringType,true);
字段。添加(字段);
StructType schema=DataTypes.createStructType(字段);
//现在,您可以创建数据帧:
DataFrame df=sqlContext.createDataFrame(rowRDD,schema);
还有几点需要注意:

  • 当您只获取第一个元素时,为什么要进行平面映射?您可以简单地执行以下操作:

    JavaRDD-urlrdd=diskfile.flatMap(line->line.split(“\t”)[0]);

  • 我假设在现实生活中,您希望从url中删除“[”(您可以在地图中轻松地执行此操作)

  • 如果您正在迁移到spark 2.0或更高版本,那么应该使用spark会话(spark)而不是sqlContext

  • 您可以创建一个包含所有列的数据框。您可以通过将所有字段添加到架构中来实现这一点(即,不只是向字段添加一个字段,而是添加所有字段)。不使用urlrdd,而是使用diskfile并在“公共行调用”创建中进行拆分。这类似于:

    JavaRDD rowd=diskfile.map(新函数(){
    @重写公共行调用(字符串记录)引发异常{
    String[]recs=record.split(“\t”)
    返回RowFactory.create(记录[0],记录[1],…);
    }
    });

  • 您可以直接创建它:只需使用

    sqlContext.read.option(“sep”、“\t”).csv.load(文件名、模式)


导入:

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类。我建议您编写日志行,其中包含URL、日期、时间、方法、目标等成员

public static class Url implements Serializable {
  private String value;

  public String getValue() {
    return value;
  }

  public void setValue(String value) {
    this.value = value;
  }
}  
从文本文件创建Url对象的RDD

JavaRDD<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;
    }
  });
JavaRDD urlsRDD=spark.read()
.textFile(“/Users/karuturi/Downloads/log.txt”)
.javaRDD()
.map(新函数(){
@凌驾
公共Url调用(字符串行)引发异常{
String[]parts=line.split(\\t“);
Url=新Url();
setValue(部分[0].replaceAll(“[”,”);
返回url;
}
});
从RDD创建数据帧

Dataset<Row> urlsDF = spark.createDataFrame(urlsRDD, Url.class);
Dataset urlsDF=spark.createDataFrame(urlsRDD,Url.class);


import sqlContext.implicits.\ spark javaYeah中不支持的命令很抱歉刚才看到了这一点。最好的替代方法是使用sqlContext来读取文件。因为将rdd转换为dataframe会使用反射来减少额外的计算,所以请使用sqlContext来读取文件。如果我想使用
S来转换
JavaRDD
,该怎么办在其中解析向量
JavaRDD<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;
    }
  });
Dataset<Row> urlsDF = spark.createDataFrame(urlsRDD, Url.class);