DataFrame是一种不可变的分布式数据集,这种数据集被组织成指定的列,类似于关系数据库中的表。
1、Python 与RDD之间的通信
每当使用RDD执行PySpark程序时,潜在地需要巨大的开销来执行作业。如下图所示,在PySpark驱动器中,Spark Context通过Py4j启动一个使用JavaSparkContext的JVM。所有的RDD转换最初都映射到Java中的PythonRDD对象。一旦这些任务被推送到Spark工作节点,PythonRDD对象就使用管道(pipe)启动Python的子进程(subprocess),发送代码和数据到Python中进行处理:
2、Catalyst优化器
Spark SQL引擎较快的主要原因是Catalyst优化器,相对立即处理查询来说,Spark引擎的Catalyst优化器编译并优化了逻辑,而且还有一个能够确保生成最有效的物理计划的成本优化器,如下图:
3、代码
#!/usr/bin/python
# encoding: utf-8
from pyspark.sql import SparkSession
from pyspark.sql import Row
from pyspark.sql.types import *
# 首先将生成的数据创建一个DataFrame。先创建stringJSONRDD,然后将它转换成一个DataFrame。下面这段代码用
# JSON格式创建一个由几个游泳选手(ID、名字、年龄、眼镜颜色)组成的RDD。
#
park = SparkSession.builder.appName('my_test').getOrCreate()
sc = spark.sparkContext
# 生成自己的JSON数据
stringJSONRDD = sc.parallelize((
"""
{"id":"123",
"name":"Katie",
"age":19,
"eyeColor":"brown"
}""",
"""
{"id":"234",
"name":"Michael",
"age":22,
"eyeColor":"green"
}""",
"""
{"id":"345",
"name":"Simone",
"age":23,
"eyeColor":"blue"
}""",
))
# 创建DataFrame
swimmersJSON = spark.read.json(stringJSONRDD)
# 创建临时表
swimmersJSON.createOrReplaceTempView("swimmesJSON")
# DataFrame API 查询
swimmersJSON.show()
# 输出结果
# +---+--------+---+-------+
# |age|eyeColor| id| name|
# +---+--------+---+-------+
# | 19| brown|123| Katie|
# | 22| green|234|Michael|
# | 23| blue|345| Simone|
# +---+--------+---+-------+
# # SQL查询
# spark.sql("select * from swimmersJSON").collect()
swimmersJSON.printSchema()
# 输出结果
# root
# |-- age: long (nullable = true)
# |-- eyeColor: string (nullable = true)
# |-- id: string (nullable = true)
# |-- name: string (nullable = true)
#======================从RDD到DataFrame的转换=======================
# 有两种转换方式,使用反射推断模式和编程方式指定模式
# 指定模式,并生成csv数据
stringCSVRDD = sc.parallelize([
(123,'katie',19,'brown'),
(234,'Michael',22,'green'),
(345,'Simone',23,'blue')
])
# 首先根据以下[schema]变量将模式编码成一个字符串,然后利用StructType和StructFieid定义模式。
# 指定模式
schema = StructType([
StructField("id",LongType(),True),
StructField("name",StringType(),True),
StructField("age",LongType(),True),
StructField("eyeColor",StringType(),True)
])
# 其中StructField():name:该字段的名字
# DataType:该字段的数据类型
# Nullable:指示次字段的值是否为空
# 对RDD应用该模式并且创建DataFrame
swimmers = spark.createDataFrame(stringCSVRDD ,schema)
# 之后,用stringCSVRDD(即生成的csv数据)创建的模式(schema),并且创建一个临时视图,使用SQL查询。
# 利用DataFrame创建一个临时视图
swimmers.createOrReplaceTempView("swimmers")
swimmers.printSchema()
# 输出结果
# root
# |-- id: long (nullable = true)
# |-- name: string (nullable = true)
# |-- age: long (nullable = true)
# |-- eyeColor: string (nullable = true)
#=================DataFrame的行数================
swimmers.count()
#================筛选句子(filter子句)=============
# 获取age = 22 的id
swimmers.select("id","age").filter("age = 22").show()
# 上诉查询的另外一种方式
swimmers.select(swimmers.id,swimmers.age).filter(swimmers.age == 22).show()
# 获取eyeColor like 'b%'的(name)名字,(eyeColor)眼镜颜色
swimmers.select("name","eyeColor").filter("eyeColor like 'b%'").show()
# ===============利用sql查询===========
# 行数
spark.sql("select count(1) from swimmers").show()
# 用SQL获得age=22的id,age
spark.sql("select id,age from swimmers where age = 22").show()
# 获取eyeColor like 'b%'的(name)名字,(eyeColor)眼镜颜色
spark.sql("select name,eyeColor from swimmers where eyeColor like 'b%'").show()