web-dev-qa-db-fra.com

Conversion de JavaRDD en DataFrame dans Spark java

J'essaie de traiter le LogFile. J'ai d'abord lu le fichier journal et divisé ces fichiers selon mes besoins et enregistré chaque colonne dans JavaRDD distinct. Maintenant, je dois convertir ces JavaRDD en DataFrames pour les opérations futures. Voici le code que j'ai essayé jusqu'à présent:

         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);

et voici comment j'essaie de convertir JavaRDD en DataFrame:

DataFrame fileDF = sqlContext.createDataFrame(urlRDD, Model.class);

Mais la ligne ci-dessus ne fonctionne pas. Je porte à confusion sur Model.class.

quelqu'un peut-il me suggérer.

Merci.

9
Satish Karuturi

Importations:

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;

Créez une classe POJO pour l'URL. Je vous recommande d'écrire pour la ligne de journal qui se compose de l'url, la date, l'heure, la méthode, la cible, etc., etc. en tant que membres

public static class Url implements Serializable {
  private String value;

  public String getValue() {
    return value;
  }

  public void setValue(String value) {
    this.value = value;
  }
}  

Créer un RDD d'objets Url à partir d'un fichier texte

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;
    }
  });

Créer un DataFrame à partir de RDD

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

RDD vers DataFrame - Spark 2.
RDD vers DataFrame - Spark 1.6

20
mrsrinivas

Vous pouvez faire quelque chose comme (je convertis à la volée à partir de scala alors excusez toutes les fautes de frappe):

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);    

Quelques notes supplémentaires:

  • Pourquoi planifiez-vous alors que vous ne prenez que le premier élément? Vous auriez pu simplement faire:

    JavaRDD<String> urlrdd=diskfile.flatMap(line -> line.split("\t")[0]);

  • Je suppose que dans la vraie vie, vous voudriez supprimer le "[" de l'url (vous pouvez facilement le faire sur la carte).

  • Si vous passez à spark 2.0 ou version ultérieure, alors au lieu de sqlContext, vous devez utiliser spark session (spark)).

  • Vous pouvez créer une seule trame de données avec toutes les colonnes. Vous pouvez le faire en ajoutant tous les champs au schéma (c'est-à-dire qu'au lieu de simplement faire un seul ajout aux champs, ajoutez-les tous). Au lieu d'utiliser urlrdd, utilisez diskfile et effectuez le fractionnement à l'intérieur de la création de "l'appel de ligne public". Ce serait quelque chose comme ceci:

    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], ...); } });

  • Vous pouvez le créer directement: utilisez simplement

    sqlContext.read.option("sep","\t").csv.load(filename,schema)

5
Assaf Mendelson

Mettez simplement vos données à plat selon le tableau à 7 colonnes et utilisez l'extrait de code ci-dessous

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);
4
FaigB

Vous pouvez directement lire le fichier en utilisant sqlContext directement

Utiliser la méthode de lecture de sqlContext

Pour plus d'informations, vous pouvez suivre ce lien

https://spark.Apache.org/docs/1.6.0/sql-programming-guide.html#creating-dataframes

Ou vous pouvez importer le

import sqlContext.implicits.*;

Utilisez ensuite la méthode toDF() sur rdd pour convertir en dataframe.

0
Akash Sethi