spark中的Dataset和DataFrame

参考《Spark与Hadoop大数据分析》Venkat Ankam和官方文档。

利用DataFrame进行分析

创建DataFrame

从spark2.0及更高版本开始,SparkSession成为了关系型功能的入口点。当使用Hive时,SparkSession必须使用enableHiveSupport方法创建。

从结构化数据文件中读取

#pyspark
df = spark.read.parquet("xxx.parquet")
df2 = spark.read.json("xxx.json") 

使用列表、模式和默认数据类型创建DataFrame

myList = [(50, "DataFrame"), (60, "pandas")]
myschema = ['col_1', 'col_2']
df = spark.createDataFrame(myList,myschema)

RDD转换成DataFrame来创建DataFrame。

myList = [(50, "DataFrame"), (60, "pandas")]
myschema = ['col_1', 'col_2']
df = sc.parallelize(myList).toDF(myschema)
df.printSchema()

Hive表中创建DataFrame

sample_07 = spark.table("sample_07")
sample_07.show()
spark.sql("select * from xxx").show()

外部数据库

首先把/usr/lib/hive/mysql-connector-java.jar复制到Spark的JAR包目录,

df = spark.read.format('jdbc').options(url='jdbc:mysql://地址', dbtable='表名', user='用户名', password='密码').loads
df.show()

使用.rdd将DataFrame转换为RDD

df_rdd = df.rdd
df_rdd.show()

常用的Dataset和DataFrame操作

输入输出数据

read:为任何数据提供通用读取功能
write:为任何数据源提供通用写功能

基本函数

1,As[U]:返回把记录映射到特定类型的新Dataset。
2,toDF:返回带有重命名列的新DataFrame。
3,explain:将(逻辑或物理)计划打印到控制台,用于调试。
4,printSchema:以树形格式把模式打印出来。
5, createTempView:使用给定的名称将当前DataFrame注册为临时表。
6,cache()或persist():根据指定的持久化级别把Dataset持久化。

DSL函数domain-specific-language (DSL)

域特定语言函数,是用于分析的。这些函数是延迟的,不会启动执行。
agg:以不分组的方式在整个Dataset/DataFrame上进行聚合。
distinct:返回一个带有唯一行的新的Dataset/DataFrame。
drop:返回一个删除了一列的新Dataset/DataFrame。
filter:利用给定的条件对行进行过滤。
join:利用给定的join表达式与另一个Dataset/DataFrame进行join操作。
limit:仅仅提取前n行,返回一个新的Dataset/DataFrame。
sort:返回一个按升序对指定的列进行排序后的新Dataset/DataFrame。
groupby:利用指定的列对Dataset/DataFrame进行分组。
unionAll:返回一个包含对两个DataFrame的行进行union产生的新Dataset/DataFrame。
na:用于处理缺失值或空值。
示例:

#pyspark shell
#创建一个DataFrame
df = spark.createDataFrame([(1, 2, 3), (4, 5, 6)], ['a', 'b', 'c'])
df.show()
#结果:含有a,b,c三列的DataFrame, 和pandas中的DataFrame非常像。
+---+---+---+
|  a|  b|  c|
+---+---+---+
|  1|  2|  3|
|  4|  5|  6|
+---+---+---+

#以列表的形式返回df的字段名: ['a', 'b', 'c']
df.columns
#统计数据表的行数:2
df.count()
#选择a列
df.a
#协方差cov(),计算a列和b列的协方差covariance:4.5
df.cov('a', 'b')

#创建临时表:createGlobalTempView(name) 和createTempView(name),两个临时表的周期不一样,前者和spark application相关,后者和spark sessione 有关。
df.createGlobalTempView("people")
df_2 = spark.sql('select * from global_temp.people')
df_2.show()
+---+---+---+
|  a|  b|  c|
+---+---+---+
|  1|  2|  3|
|  4|  5|  6|
+---+---+---+
df.createTempView('dd')
spark.sql('select * from dd').show()

#筛选filter(),仍返回一个DataFrame
df_2 = df.filter(df.a>1)
#也可以用pandas中的用法,等价于:df_2 = df[df['a']>1]
df_2.show()
+---+---+---+
|  a|  b|  c|
+---+---+---+
|  4|  5|  6|
+---+---+---+
#按列筛选select(),仍返回一个DataFrame
df.select('a', 'c').show()
#或者用pandas中的方式:df[['a', 'c']].show()
+---+---+
|  a|  c|
+---+---+
|  1|  3|
|  4|  6|
+---+---+
#df.dtypes,查看每一列的数据类型,和pandas中的用法一样。
[('a', 'bigint'), ('b', 'bigint'), ('c', 'bigint')]

#describe(), 返回一个DataFrame,用于查看数据表的描述情况,包括最佳,计数等 
df.describe().show()
+-------+------------------+------------------+------------------+
|summary|                 a|                 b|                 c|
+-------+------------------+------------------+------------------+
|  count|                 2|                 2|                 2|
|   mean|               2.5|               3.5|               4.5|
| stddev|2.1213203435596424|2.1213203435596424|2.1213203435596424|
|    min|                 1|                 2|                 3|
|    max|                 4|                 5|                 6|
+-------+------------------+------------------+------------------+

#drop(),删除特定列,返回新的DataFrame
df.drop('a', 'b').show()
+---+
|  c|
+---+
|  3|
|  6|
+---+
#distinct()去掉重复行, 返回一个DataFrame, 考虑所有的列。
df.distinct().show()
#drop_duplicates()(等价于dropDuplicates()),可以对特定的列进行去重,列名放在列表中。
df.drop_duplicates(['a', 'b'])#只考虑a, b列相同的行数,保留第一行。

#删除含有空值的行,并返回一个去空值后的DataFrame,可以只考虑特定的列。
dropna(how='any', thresh=None, subset=None)
how 为'any'表示删除含有空值的行,'all'表示删除全为空值的行。
df.dropna('any', None, ['a']).show()

#df.fillna()填充空缺值,返回一个DataFrame。如果参数为单个值,即所有的空缺值用该值填充。参数也可以是字典,对不同字段中的空缺值填充不同的值。
df.fillna(0)
df.fillna({'a':0, 'b':'null'})

#连接join(), 第三个参数:inner, left, right。类似mysql中的连接操作。
df.join(df_2, df.a == df_2.a, 'left').show()
+---+---+---+----+----+----+                                                    
|  a|  b|  c|   a|   b|   c|
+---+---+---+----+----+----+
|  1|  2|  3|null|null|null|
|  4|  5|  6|   4|   5|   6|
+---+---+---+----+----+----+
#crossJoin():笛卡尔积cartesian product
df.crossJoin(df).show()
+---+---+---+---+---+---+
|  a|  b|  c|  a|  b|  c|
+---+---+---+---+---+---+
|  1|  2|  3|  1|  2|  3|
|  1|  2|  3|  4|  5|  6|
|  4|  5|  6|  1|  2|  3|
|  4|  5|  6|  4|  5|  6|
+---+---+---+---+---+---+

#foreach(),类似于很多编程语言中foreach(),传入一个函数,但作用于DataFrame中所有的行
#foreachPartition(), 作用于DataFrame中的partition。
df.foreach(lambda x:print(x))
结果:
Row(a=1, b=2, c=3)
Row(a=4, b=5, c=6)

df.foreachPartition(lambda x : print(x))
结果:


内置函数、聚合函数、窗口函数

内置函数:和用户自定义函数一样,对单个行进行操作,计算出单个值。如substr、round。
聚合函数:对若干行进行操作,计算出单个值。如:min、max、sum、mean、first、last、avg、count、countDistinct和approxCountDistinct。
窗口函数:对与当前行相关的若干行进行操作。如:rank、denseRank、percentRank、ntile和rowNumber。

动作

collect:返回一个包含该DataFrame中所有行的数组。
count:对该 DataFrame 中的行数进行计数。
describe:对数值列计算其统计数据。
show:将前n行打印到控制台。
take:以行的列表的形式返回前n行。

RDD操作

也可以在DataFrame上运用RDD操作,如:map、flatMap、coalesce、repartition、foreach、toJson和toJavaRDD, 这些在DSL中没有的。

Data Source API

Data Source API提供了一个使用Spark SQL加载和存储数据的单一接口。通过spark.sql.sources.default配置属性,设置默认数据源为parquet,可以根据需要修改。

内置数据源

包括:text, json, parquet, orc, jdbc和csv。

#读
df = spark.read.json("xxx.json")#或者像下面这样写
df = spark.read.load("xxx.json", format='json')#默认是parquet,如果是parquet,可以不写format。
#写
df.write.json("newjson_dir")#或者像下面这样写
df.write.format("json").save("newjson_dir")

外部数据源

外部数据源在spark packages中可用,不包括在spark中。
spark packages 提供了用于从NoSQL数据库(HBase、Cassandra等)读取不同文件格式和数据的组件包。当你想要在应用程序中包含一个spark组件包时,需要使用–packages命令行选项,加上以逗号分隔的jar包的maven坐标(coordinate)列表, 把它包含在驱动进程和执行进程的classpath上。

AVRO

XML

pandas

基于DataFram的Spark-on-HBase连接器

Hive on Spark

Hive on Spark 是为了使现有Hive用户能够直接在Spark执行引擎,而不是在MapReduce上运行Hive查询而创建的。在Hive或beeline客户端中将执行引擎更改为spark。

hive>> set hive.execution.engine=spark;#hive命令行

你可能感兴趣的:(其他)