https://blog.csdn.net/FlySky1991/article/details/79569846
DataFrame是一种分布在集群节点中的不可变的分布式数据集,这种数据集是 以RDD为基础的,其被组织成指定的列,类似于关系数据库的二维表格和Python中的Pandas.DataFrame。DataFrame本身带有Schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型。DataFrame的一个主要优点是:Spark引擎一开始就构建了一个逻辑执行计划,而且执行生成的代码是基于成本优化程序确定的物理计划,DataFrame的引入能够显著提高PySpark中的查询速度。
本文主要结合一些简单的案例介绍下DataFrame的基本操作。
1.创建一个DataFrame
完整的示例代码如下所示:
from pyspark import SparkConf, SparkContext
from pyspark.sql import SparkSession
import json
conf = SparkConf().setMaster("local").setAppName("My App")
sparkSession1 = SparkSession.builder.config(conf = conf).getOrCreate()
print("spark初始化完成")
my_spark_context = sparkSession1.sparkContext
print("获取spark上下文成功·······")
#生成一段JSON数据
JSON_string_RDD = my_spark_context.parallelize(("""
{"id":"123",
"name":"Katie",
"age":19,
"eyeColor":"brown"
}""",
"""{
"id":"456",
"name":"Michael",
"age":21,
"eyeColor":"blue"
}""",
"""{
"id":"789",
"name":"Jack",
"age":23,
"eyeColor":"Black"
}"""))
#输出RDD的全部信息(此时这个RDD的每个元素都是一个可用json解析的字符串)
print(JSON_string_RDD.collect())
#将RDD转化为一个DataFrame
my_DataFrame = sparkSession1.read.json(JSON_string_RDD)
#1.输出DataFrame中的元素
print("1.输出DataFrame中的元素:\n")
my_DataFrame.show()
#2.输出DataFrame的Schema模式(名称和类型)
print("2.输出DataFrame的Schema模式(名称和类型):\n")
my_DataFrame.printSchema()
输出结果如下所示:
spark初始化完成
获取spark上下文成功·······
['\n {"id":"123",\n"name":"Katie",\n"age":19,\n"eyeColor":"brown"\n }', '{\n"id":"456",\n"name":"Michael",\n"age":21,\n"eyeColor":"blue"\n }', '{\n"id":"789",\n"name":"Jack",\n"age":23,\n"eyeColor":"Black"\n }']
1.输出DataFrame中的元素:
+---+--------+---+-------+
|age|eyeColor| id| name|
+---+--------+---+-------+
| 19| brown|123| Katie|
| 21| blue|456|Michael|
| 23| Black|789| Jack|
+---+--------+---+-------+
2.输出DataFrame的Schema模式(名称和类型):
root
|-- age: long (nullable = true)
|-- eyeColor: string (nullable = true)
|-- id: string (nullable = true)
|-- name: string (nullable = true)
2.DataFrame基本操作
2.1 RDD的交互操作
从RDD变换到DataFrame主要有两种不同的方法:使用反射推断模式和以编程方式指定模式。
(1)使用反射推断模式
在创建DataFrame时,如果没有指定模式,就会使用printSchema()方法自带的模式定义。上面的DataFrame示例就是通过这种方法创建的。这种方法能够更为简便的创建DataFrame,但不能精细地控制DataFrame的模式。
(2)以编程方式指定模式
和前一种方法相比,以编程方式指定DataFrame模式虽然更为麻烦一些,但能够精细地控制DataFrame的模式。示例代码如下所示:
from pyspark import SparkConf, SparkContext
from pyspark.sql import SparkSession
import json
conf = SparkConf().setMaster("local").setAppName("My App")
sparkSession1 = SparkSession.builder.config(conf = conf).getOrCreate()
print("spark初始化完成")
my_spark_context = sparkSession1.sparkContext
print("获取spark上下文成功·······")
#导入类型
from pyspark.sql.types import *
#生成以逗号分隔的数据
string_CSV_RDD = my_spark_context.parallelize([
(123,'Katie',19,'brown'),
(345,'Michael',20,'green'),
(567,'Simone',21,'blue')])
#指定模式
schema = StructType([
StructField("id",LongType(),True),
StructField("name",StringType(),True),
StructField("age",LongType(),False),
StructField("eyeColor",StringType(),True),])
#对RDD应用该模式并且创建DataFrame
my_dataframe = sparkSession1.createDataFrame(string_CSV_RDD,schema)
#利用DataFrame创建一个临时视图
my_dataframe.createOrReplaceTempView("lalala")
#输出DataFrame中每个字段的类型
print("输出DataFrame中每个字段的类型:\n")
my_dataframe.printSchema()
通过printSchema输出的字段类型如下所示:
spark初始化完成
获取spark上下文成功·······
输出DataFrame中每个字段的类型:
root
|-- id: long (nullable = true)
|-- name: string (nullable = true)
|-- age: long (nullable = false)
|-- eyeColor: string (nullable = true)
2.2 DataFrame API查询
类似于RDD,在DataFrame中也可以通过 .count()、.filter()、.show()、.take() 等来查询DataFrame中的数据。示例代码如下所示:
#1.输出DataFrame中的行数
print("1.输出DataFrame中的行数:\n{}".format(my_dataframe.count()))
#2.用filter获取age=20的id
print("2.输出DataFrame中age=20的id:\n")
my_dataframe.select("id","age").filter("age=20").show()
#3.获取eyeColor like 'b%'的id,name,eyeColor
print("3.输出DataFrame中eyeColor like 'b%'的id,name,eyeColor:\n")
my_dataframe.select("id","name","age").filter("eyeColor like 'b%'").show()
输出结果如下所示:
2.3 SQL查询
SQL查询DataFrame数据的示例代码如下所示:
#首先你需要为你即将进行SQL操作的dataFrame创建一个视图view,view的名字相当于数据库的表名
my_dataframe.createOrReplaceTempView("lalala")
#1.获取DataFrame中数据的行数
print("1.利用SQL查询输出DataFrame中数据的行数:\n")
sparkSession1.sql("select count(1) as num from lalala").show()
#2.利用where子句获取age=21的id,age
print("2.利用where子句获取age=21的id,age:\n")
sparkSession1.sql("select id,age from lalala where age = 21").show()
#3.利用where子句获取DataFrame中eyeColor like 'b%'的所有字段信息
print("3.利用where子句获取DataFrame中eyeColor like 'b%'的所有字段信息:\n")
sparkSession1.sql("select * from lalala where eyeColor like 'b%'").show()
输出结果如下所示:
总结
根据本节的学习,我们已经了解了好几种创建DataFrame方式:
# 方式一,从json字符串数组的RDD对象创建DataFrame
sparkSession1.read.json(JSON_string_RDD)
# 方式二,从CSV格式的tuple数组的RDD创建DataFrame
sparkSession1.createDataFrame(CSV_tuple_RDD,schema)
#它还有一个等价写法:
sparkSession1.createDataFrame([
(1,175,72,28,'M',10000),
(2,171,70,45,'M',None),
(3,172,None,None,None,None),
(4,180,78,33,'M',None),
(5,None,48,54,'F',None),
(6,160,45,30,'F',5000),
(7,169,65,None,'M',5000),],
['id','height','weight','age','gender','income'])