DataFrames
DataFrames 和 Dataset 是类似于表的集合,具有定义好的行和列。每个列必须是具有与所有其他列相同的行数(如果指定值缺失,可以使用null),并且每个列都是类型信息,这些信息必须与集合中的每一行一直。这是因为内部有一个 schema 的概念,其定义了分布式集合中存储的数据类型。
schema
schema 定义了 DataFrame 的列名和类型。可以手动定义 schemas 模式或从数据源读取 schemas 模式。 Schema包含列类型,用于申明什么列存储了什么类型的数据。
Rows
一行 Row 只是表示数据的一条记录。 DataFrame 中的每条记录必须是 Row 类型。
Column
column 表示一个简单的类型,如 integer 或 string,复杂类型,如 array ,map, null。Spark 将跟踪所有这类类型的信息,并提供多种方式对 columns 进行装潢
Spark DataType
Spark 有大量的内部类型表示,这样就可以很容易地引用在特定的语言中,与Spark类型想匹配的类型。其位于 import org.apache.spark.sql.types.DataTypes 类中。
实战演练
使用自定义 schema 创建 DataFrame
-- java
/**
* 使用List<Row>、schema创建DataFrame
* 注意:创建StructField、StructType,要使用DataTypes的工厂方法。
*/
List<Row> rows=new ArrayList<Row>();
rows.add(RowFactory.create("zhangsan",20,"beijing"));
rows.add(RowFactory.create("lisi",18,"shanghai"));
StructField[] fields=new StructField[]{
DataTypes.createStructField("name", DataTypes.StringType, false),
DataTypes.createStructField("age", DataTypes.IntegerType, false),
DataTypes.createStructField("address", DataTypes.StringType, false)
};
StructType schema=DataTypes.createStructType(fields);
Dataset<Row> listSchemaDF=spark.createDataFrame(rows, schema); //DataFrame
listSchemaDF.show();
listSchemaDF.printSchema();
--- scala
/**
* 使用createDataFrame(rdd,schema)方法创建DataFrame
*/
val schema=StructType(List(
StructField("name",StringType,nullable=false),
StructField("age",IntegerType,nullable=false),
StructField("address",StringType,nullable=false),
StructField("birthday",DateType,nullable=false)
))
val rowRDD=spark.sparkContext.parallelize(Seq(
Row("zhangsan",10,"beijing",java.sql.Date.valueOf("2008-01-01")),
Row("lisi",20,"shanghai",java.sql.Date.valueOf("1998-01-01"))
), 2) // parallelize 为 2.
val rddSchemaDF=spark.createDataFrame(rowRDD, schema)
rddSchemaDF.show()
rddSchemaDF.printSchema()