Spark创建DataFrame

1. DataFrame

在Spark中可以通过RDD转换为DataFrame,也可以通过DataFrame转化为RDD,DataFrame可以理解为数据的一个格式,实质show()就是一张表。

读取数据构造DataFrame主要有以下几种方式:

  • 从Json文件中读取
  • 通过SQLContext构造类对象构造DataFrame
  • 动态创建Schema构造当前的DataFrame结构
  • 从parquet文件中读取
  • 从MySQL中读取数据
  • 从Hive中读取数据

2. 从json文件读取构造DataFrame

	public static void main(String[] args) {
        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("dfTest");
        JavaSparkContext sc = new JavaSparkContext(conf);
        SQLContext sqlContext = new SQLContext(sc);

        DataFrame df1 = sqlContext.read().format("json").json("./scala/student");
        df1.show();
        // 通过注册临时表的方法,可以使用我们比较熟悉的方式查询当前数据
        df1.registerTempTable("student");
//        DataFrame df2 = sqlContext.sql("select name,age from student where age > 23");
        // 通过最原始的方式查询当前表的一些数据,利用DataFrame可以直接查询,其实质就是一张表
        // 如果注册成为了一张临时表,此时通过SQLContext可以利用我们的查询语句进行直接的查询
        DataFrame df2 = df1.select(df1.col("name"), df1.col("age")).where(df1.col("age").lt(24));

        df2.show();

        sc.stop();
    }

直接读取然后格式化为json格式的信息即可。

2. 通过文件读取,动态构建类的RDD

public static void main(String[] args) {
        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("dfTestTwo");
        JavaSparkContext sc = new JavaSparkContext(conf);
        SQLContext sqlContext = new SQLContext(sc);
        JavaRDD<String> rdd1 = sc.textFile("./scala/person");

        // 转换为Person的RDD
        JavaRDD<Person> personRdd = rdd1.map(new Function<String, Person>() {
            @Override
            public Person call(String s) throws Exception {
                String[] split = s.split(",");
                return new Person(Integer.valueOf(split[0]), split[1], split[2]);
            }
        });
        // 构建DataFrame整体的框架
        DataFrame df1 = sqlContext.createDataFrame(personRdd, Person.class);
        df1.show();

        df1.registerTempTable("person");

        DataFrame sql = sqlContext.sql("select name,age,address from person where age in (23,24)");
        sql.show();

        // 现在通过DataFrame构建person对象
        // 首先要获取当前dataFrame的一个JavaRDD对象
        JavaRDD<Row> rowJavaRDD = sql.javaRDD();
        // 然后将当前的JavaRDD<Row>对象转化为JavaRDD<Person>对象即可
        JavaRDD<Person> personJavaRDD = rowJavaRDD.map(new Function<Row, Person>() {
            @Override
            public Person call(Row row) throws Exception {
                Person person = new Person();
                person.setAge(Integer.valueOf(row.getAs("age") + ""));
                person.setName(row.getAs("name") + "");
                person.setAddress(row.getAs("address") + "");
                return person;
            }
        });

        personJavaRDD.foreach(new VoidFunction<Person>() {
            @Override
            public void call(Person person) throws Exception {
                System.out.println(person);
            }
        });

        sc.stop();
    }

首先需要构造一个当前的类,然后读取类的信息,然后构造当前类的一个DataFrame

3. 动态创建Schema构造DataFrame

	public static void main(String[] args) {
        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("dfTestThree");
        JavaSparkContext sc = new JavaSparkContext(conf);
        SQLContext sqlContext = new SQLContext(sc);
        JavaRDD<String> rdd1 = sc.textFile("./scala/person");
        // 动态构建Schema
        JavaRDD<Row> rowJavaRDD = rdd1.map(new Function<String, Row>() {
            @Override
            public Row call(String s) throws Exception {
                String[] split = s.split(",");
                return RowFactory.create(split[1], Integer.parseInt(split[0]), split[2]);
            }
        });

        // 动态创建schema,字段需要匹配操作
        List<StructField> fields = Arrays.asList(
                DataTypes.createStructField("name", DataTypes.StringType, true),
                DataTypes.createStructField("age", DataTypes.IntegerType, true),
                DataTypes.createStructField("address", DataTypes.StringType, true)
        );

        // 创建schema,结构
        StructType schma = DataTypes.createStructType(fields);

        // 动态创建DataFrame
        DataFrame dataFrame = sqlContext.createDataFrame(rowJavaRDD, schma);
        dataFrame.show();


        sc.stop();

    }

构造属性集合,然后构建结构类型Schema,最后通过SQLContext构造DataFrame

4. 从parquet文件中读取构造

parquet实质也是Spark主动生成的一种压缩数据格式的文件。

	public static void main(String[] args) {
        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("parquent");
        JavaSparkContext sc = new JavaSparkContext(conf);
        SQLContext sqlContext = new SQLContext(sc);
        JavaRDD<String> javaRDD = sc.textFile("./scala/student");
        DataFrame df = sqlContext.read().json(javaRDD);

        df.write().mode(SaveMode.Ignore).format("parquet").save("./scala/parquent");

        DataFrame load = sqlContext.read().format("parquet").load("./scala/parquent");
        load.show();

        sc.stop();

    }

5. 从MySQL中读取数据构造DataFrame

通过远程连接MySQL获取数据,但是获取数据之前,需要先将各个字段给构造好。

	public static void main(String[] args) {
        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("dfSql");
        conf.set("spark.sql.shuffle.partitions","200");
        JavaSparkContext sc = new JavaSparkContext(conf);

        SQLContext sqlContext = new SQLContext(sc);

        /**
         * 人为构建DataFrame然后将数据写入其中即可写的其实就是当前的一个DataFrame
         * 即构建DataFrame,带入的数据即是我们构建时写入的数据
         *
         * 构建DataFrame的话,首先需要读入数据,然后通过StructField构建当前的一个表格属性的List
         * 然后通过DataTypes构建当前的数据类型StructType,最后通过sqlContext构建当前的一个DataFrame
         */
        JavaRDD<String> javaRDD = sc.parallelize(Arrays.asList("1 Caoduanxi 24", "2 Zhangsan 21", "3 Lisi 22"));
        JavaRDD<Row> map = javaRDD.map(new Function<String, Row>() {
            @Override
            public Row call(String s) throws Exception {
                String[] s1 = s.split(" ");
                return RowFactory.create(Integer.parseInt(s1[0] + ""), s1[1], s1[2]);
            }
        });

        List<StructField> structFields = new ArrayList<>();
        structFields.add(DataTypes.createStructField("id", DataTypes.IntegerType, true));
        structFields.add(DataTypes.createStructField("name", DataTypes.StringType, true));
        structFields.add(DataTypes.createStructField("age", DataTypes.StringType, true));

        StructType structType = DataTypes.createStructType(structFields);

        DataFrame df = sqlContext.createDataFrame(map, structType);

        Properties properties = new Properties();
        properties.setProperty("user", "***");
        properties.setProperty("password", "****");

        df.write().mode(SaveMode.Append).jdbc("jdbc:mysql://106.15.1xx.xx:3306/study", "person", properties);

        /*
            填写参数获取此时数据库的信息
         */
//        Map<String,String> map = new HashMap<String,String>();
//        // 参数也可以一个一个的传入
//        map.put("url","jdbc:mysql://106.15.125.75:3306/study");
//        map.put("driver","com.mysql.jdbc.Driver");
//        map.put("user","root");
//        map.put("password","123456");
//        map.put("dbtable","logs");
//
//        DataFrame df = sqlContext.read().format("jdbc").options(map).load();
//        df.show();

        // 单独录入也可以,但是需要format格式为jdbc格式,然后需要load一下数据才可以被加载位当前的DataFrame
        DataFrameReader dfReader = sqlContext.read().format("jdbc");
        dfReader.option("url", "jdbc:mysql://106.15.125.75:3306/study");
        dfReader.option("driver", "com.mysql.jdbc.Driver");
        dfReader.option("user", "root");
        dfReader.option("password", "123456");
        dfReader.option("dbtable", "logs");

//        DataFrame df2 = dfReader.load();
//        df2.show();
//
//        df2.registerTempTable("logs");
//        DataFrame sql = sqlContext.sql("select * from logs");
//        sql.show();
//
//        // 将结果写回mysql中
//        Properties properties = new Properties();
//        properties.setProperty("user", "root");
//        properties.setProperty("password", "123456");
//        // 如果自己认为构造一张表出来的话,还是可以直接放入到其中实现的
//        df2.write().mode(SaveMode.Append).jdbc("jdbc:mysql://106.15.125.75:3306/study", "logs", properties);
        System.out.println("****finished****");
        sc.stop();
    }

6. 小结

数据的处理主要是通过RDD来实现的,主要是一些算子在其中主导数据的处理,但是输入的数据要想转换为RDD可处理,需要先转换为DataFrame,然后再转化为RDD,此时可以通过Transformations和Actions算子来处理即可。

Keep thinking, keep coding! 2020-9-24 南京

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值