RDD转换到DataFrames
SparkSQL有两种方法将存在的RDDS转变到DataFrames。第一种方法:使用反射来推断包含特定类型对象的RDD的schema,这种基于反射的方法可以提供更简洁的代码,并且在您编写Spark应用程序时已经了解schema时可以很好地工作。
第二种方法:使用编程接口,构造一个schema并将其应用在已知的RDD上。
利用反射机制推断schema
Spark SQL可以将Row对象的RDD转换为DataFrame,从而推断出数据类型。 通过将键/值对列表作为kwargs传递给Row类来构造行。 此列表的键定义表的列名称,并通过对整个数据集进行采样来推断类型,类似于对JSON文件执行的推断。
from pyspark.sql import Row
sc = spark.sparkContext()
# 加载文本文件并将每行转换为Row
lines = sc.textFile("examples/src/main/resources/people.txt")
parts = lines.map(lambda l: l.split(","))
people = parts.map(lambda p: Row(name=p[0], age=int(p[1])))
# 推断schema,将DataFrame注册成表
schemaPeople = spark.createDataFrame(people)
schemaPeople.createOrReplaceTempView("people")
# SQL可以在已注册为表的DataFrame上运行.
teenagers = spark.sql("SELECT name FROM people WHERE age >= 13 AND age <= 19")
# SQL查询的结果是Dataframe对象。
# rdd返回内容为 :class:`pyspark.RDD` of :class:`Row`.
teenNames = teenagers.rdd.map(lambda p: "Name: " + p.name).collect()
for name in teenNames:
print(name)
# Name: Justin
编程接口,构造一个schema
当无法提前定义kwargs字典时(例如,记录结构以字符串形式编码,或者文本数据集将被解析,字段将以不同方式为不同用户进行投影),可以使用编程方式创建DataFrame 三个步骤。
-
从原始RDD创建元组或列表的RDD;
-
创建由StructType表示的schema,该schema与步骤1中创建的RDD中的元组或列表的结构相匹配;
-
通过SparkSession提供的createDataFrame方法将schema应用于RDD
# 导入数据类型
from pyspark.sql.types import *
sc = spark.sparkContext
# 加载文本文件,并将文本文件中的每行转换成Row.
lines = sc.textFile("examples/src/main/resources/people.txt")
parts = lines.map(lambda l: l.split(","))
# 每行转化成一个元祖.
people = parts.map(lambda p: (p[0], p[1].strip()))
# schema以字符串形式编码.
schemaString = "name age"
fields = [StructField(field_name, StringType(), True) for field_name in schemaString.split()]
schema = StructType(fields)
# 将schema应用到RDD.
schemaPeople = spark.createDataFrame(people, schema)
#使用DataFrame创建临时视图
schemaPeople.createOrReplaceTempView("people")
# SQL可以在已注册为表的DataFrame上运行.
results = spark.sql("SELECT name FROM people")
results.show()
# +-------+
# | name|
# +-------+
# |Michael|
# | Andy|
# | Justin|
# +-------+