• 生成dataset的几种方式


    1.常用的方式通过sparksession读取外部文件或者数据生成dataset(这里就不讲了)
      注: 生成Row对象的方法提一下:RowFactory.create(x,y,z),取Row中的数据使用row.getAs("列名")来获取对应的列值或者row.getInt(0),row.getString(1)(但这个要注意顺序)

       

    2.通过调用createDataFrame生成Dataset
    通过反射的方式将非json格式的RDD转换成DataFrame(不建议使用)

    自定义类要可序列化
    自定义类的访问级别是Public
    RDD转成DataFrame后会根据映射将字段按Assci码排序
    将DataFrame转换成RDD时获取字段两种方式,一种是df.getInt(0)下标获取(不推荐使用),另一种是df.getAs(“列名”)获取(推荐使用)
    关于序列化问题:
                 1.反序列化时serializable 版本号不一致时会导致不能反序列化。
                 2.子类中实现了serializable接口,父类中没有实现,父类中的变量不能被序列化,序列化后父类中的变量会得到null。
                 注意:父类实现serializable接口,子类没有实现serializable接口时,子类可以正常序列化
                3.被关键字transient修饰的变量不能被序列化。
                4.静态变量不能被序列化,属于类,不属于方法和对象,所以不能被序列化。
               另外:一个文件多次writeObject时,如果有相同的对象已经写入文件,那么下次再写入时,只保存第二次写入的引用,读取时,都是第一次保存的对象。

     1 /**方法1
     2 * 注意:
     3 * 1.自定义类必须是可序列化的
     4 * 2.自定义类访问级别必须是Public
     5 * 3.RDD转成DataFrame会把自定义类中字段的名称按assci码排序
     6 */
     7 SparkConf conf = new SparkConf();
     8 conf.setMaster("local").setAppName("RDD");
     9 JavaSparkContext sc = new JavaSparkContext(conf);
    10 SQLContext sqlContext = new SQLContext(sc);
    11 JavaRDD<String> lineRDD = sc.textFile("sparksql/person.txt");
    12 JavaRDD<Person> personRDD = lineRDD.map(new Function<String, Person>() {
    13 
    14     /**
    15     * 
    16     */
    17     private static final long serialVersionUID = 1L;
    18 
    19     @Override
    20     public Person call(String s) throws Exception {
    21           Person p = new Person();
    22           p.setId(s.split(",")[0]);
    23           p.setName(s.split(",")[1]);
    24           return p;
    25     }
    26 });
    27 /**
    28 * 传入进去Person.class的时候,sqlContext是通过反射的方式创建DataFrame
    29 * 在底层通过反射的方式获得Person的所有field,结合RDD本身,就生成了DataFrame
    30 */
    31 DataFrame df = sqlContext.createDataFrame(personRDD, Person.class); 
    32 
    33 class Person implements Serializable {
    34     private static final long serialVersionUID = -6907013906164009798L;
    35     private String Id;
    36     private String name;
    37 
    38 
    39 
    40     public void setId(String appId) {
    41         this.appId = appId;
    42     }
    43 
    44     public String getId() {
    45         return appId;
    46     }
    47 
    48     public String getname() {
    49         return detail;
    50     }
    51 
    52     public void setname(String detail) {
    53         this.detail = detail;
    54     }
    55 }
     1 //方法2:
     2 JavaRDD<String> lineRDD = sc.textFile("./sparksql/person.txt");
     3 /**
     4  * 转换成Row类型的RDD
     5  */
     6 JavaRDD<Row> rowRDD = lineRDD.map(new Function<String, Row>() {
     7 
     8     /**
     9      * 
    10      */
    11     private static final long serialVersionUID = 1L;
    12 
    13     @Override
    14     public Row call(String s) throws Exception {
    15           return RowFactory.create(//这里字段顺序一定要和下边 StructField对应起来
    16                 String.valueOf(s.split(",")[0]),
    17                 String.valueOf(s.split(",")[1]),
    18     );
    19     }
    20 });
    21 /**
    22  * 动态构建DataFrame中的元数据,一般来说这里的字段可以来源自字符串,也可以来源于外部数据库
    23  */
    24 List<StructField> asList =Arrays.asList(//这里字段顺序一定要和上边对应起来
    25     DataTypes.createStructField("id", DataTypes.StringType, true),
    26     DataTypes.createStructField("name", DataTypes.StringType, true)
    27 );
    28 StructType schema = DataTypes.createStructType(asList);
    29 /*
    30   StructType schema = new StructType(new StructField[]{
    31                         new StructField("id", DataTypes.StringType, false, Metadata.empty()),
    32                         new StructField("name", DataTypes.StringType, false, Metadata.empty()),
    33             });
    34 */
    35 //DataFrame df = sqlContext.createDataFrame(List<Row> ,schema)这个方法也可以
    36 DataFrame df = sqlContext.createDataFrame(rowRDD, schema);
     1 //方法3
     2 public static class Person implements Serializable {
     3   private String name;
     4   private int age;
     5 
     6   public String getName() {
     7     return name;
     8   }
     9 
    10   public void setName(String name) {
    11     this.name = name;
    12   }
    13 
    14   public int getAge() {
    15     return age;
    16   }
    17 
    18   public void setAge(int age) {
    19     this.age = age;
    20   }
    21 }
    22 
    23 // Create an instance of a Bean class
    24 Person person = new Person();
    25 person.setName("Andy");
    26 person.setAge(32);
    27 
    28 // Encoders are created for Java beans
    29 Encoder<Person> personEncoder = Encoders.bean(Person.class);
    30 Dataset<Person> javaBeanDS = spark.createDataset(
    31   Collections.singletonList(person),
    32   personEncoder
    33 );
    34 javaBeanDS.show();
    35 // +---+----+
    36 // |age|name|
    37 // +---+----+
    38 // | 32|Andy|
    39 // +---+----+
    40 
    41 // Encoders for most common types are provided in class Encoders
    42 Encoder<Integer> integerEncoder = Encoders.INT();
    43 Dataset<Integer> primitiveDS = spark.createDataset(Arrays.asList(1, 2, 3), integerEncoder);
    44 Dataset<Integer> transformedDS = primitiveDS.map(
    45     (MapFunction<Integer, Integer>) value -> value + 1,
    46     integerEncoder);
    47 transformedDS.collect(); // Returns [2, 3, 4]
    48 
    49 // DataFrames can be converted to a Dataset by providing a class. Mapping based on name
    50 String path = "examples/src/main/resources/people.json";
    51 Dataset<Person> peopleDS = spark.read().json(path).as(personEncoder);
    52 peopleDS.show();
    53 // +----+-------+
    54 // | age|   name|
    55 // +----+-------+
    56 // |null|Michael|
    57 // |  30|   Andy|
    58 // |  19| Justin|
    59 // +----+-------+
  • 相关阅读:
    旁友数独会伐啦?python秒解数独了解下伐啦?
    趁老王不在,和隔壁邻居斗斗地主,比比大小
    ll字段 详解 文件权限
    etc/pass命令列表
    maven配置
    linux常用汇总
    Tomcat学习笔记
    JavaEE高级-Hibernate学习笔记
    JavaEE高级-通用Mapper学习笔记
    jQueryrocket
  • 原文地址:https://www.cnblogs.com/lyy-blog/p/9814662.html
Copyright © 2020-2023  润新知