2 、SparkSQL编程入口SparkSession

1.要编写SparkSQL程序,必须通SparkSession对象

pyspark.sql.SparkSession(sparkContext, jsparkSession=None)

spark1.x之前的版本中,SparkSQL程序的编程入口是

pyspark.sql.SQLContext(sparkContext, sparkSession=None, jsqlContext=None)

这个是需要大家知道的,Spark1.xSpark2.xAPI方面变化还是挺大的!

还有一个pyspark.sql.HiveContext(sparkContext, jhiveContext=None),用于整合Hive数据仓库的,读取Hive表格需要借助HiveContext

 

2.SparkSession这个类中,有builder,通过builder去构建SparkSession实例,用法如下。

from pyspark.sql import SparkSession

spark = SparkSession.builder.master("spark://hadoopmaste:

7077").appName("test").config("spark.xxxx.conf", "some-value")

.getOrCreate()

master用于指定spark集群地址

appName用于设置app的名称

config中以keyvalue的形式进行一些配置

config可以以链式编程的方式多次调用,每次调用可设置一组keyvalue配置。而且conf中还可以传入一个关键字参数conf,指定外部的SparkConf配置对象getOrCreate,若存在sparksession实例直接返回,否则实例化一个sparksession返回

enableHiveSupport()启用对hive的支持

这些配置可以通过SparkSession上的conf属性来获取,这个conf实际上就是

RuntimeConfig对象,通过conf上的get方法获取对应的配置和通过spark.sparkContext.getConf().get获取配置是类似的。

 

3.创建DataFrame的几种常见方式

createDataFrame(data, schema=None, samplingRatio=None, verifySchema=True)这个方法。可以使用RDD或则python list获取pandas.DataFrame来创建。

schema被指定的时候,每个列的类型将会通过列来进行推断。

samplingRatio指定用于类型推断的样本的比例

verifySchema验证每行的数据类型是否符合schema的定义。

使用tuple创建DataFrame,注意对比有schema和没有指定schema的区别

l = [('liko',14,32),('alan',20,32)]
print(spark.createDataFrame(l).collect())
print(spark.createDataFrame(l, schema=['name','weight','age']).collect())

输出结果:
Setting default log level to "WARN".

To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).

[Row(_1='liko', _2=14, _3=32), Row(_1='alan', _2=20, _3=32)]

[Row(name='liko', weight=14, age=32), Row(name='alan', weight=20, age=32)]

通过使用dict字典创建DataFrame,通过字典不用指定schema,因为字典中的key就是schema

l = [{'name':'liko','age':14},{'name':'alan','age':20}]
print(spark.createDataFrame(l, schema=['name','age']).collect())

运行结果:
[Row(name='liko', age=14), Row(name='alan', age=20)]

通过RDD来创建DataFrame

l = [('liko', 14),('alan',20)]
rdd = sc.parallelize(l,3)
df = spark.createDataFrame(rdd)
df1 = spark.createDataFrame(rdd,schema=['name','age'])
df.show()
df1.show()

运行结果:

+----+---+

|  _1| _2|

+----+---+

|liko| 14|

|alan| 20|

+----+---+

 

|name|age|

+----+---+

|liko| 14|

|alan| 20|

+----+---+

通过在RDD上构建Row对象来构建DataFrame

from pyspark.sql import Row
Person = Row('name', 'age')
l = [('liko', 14),('alan',20)]
rdd = sc.parallelize(l,3)
person = rdd.map(lambda r: Person(*r))
df2 = spark.createDataFrame(person)
df2.show()

运行结果:
+----+---+

|name|age|

+----+---+

|liko| 14|

|alan| 20|

+----+---+

通过传入RDD和schema信息来构建DataFrame

from pyspark.sql.types import *
schema = StructType([StructField("name", StringType(),
True),StructField("age", IntegerType(), True)])
l = [('liko', 32),('alan',20)]
rdd = sc.parallelize(l,3)
df3 = spark.createDataFrame(rdd, schema)
df3.show()

+----+---+

|name|age|

+----+---+

|liko| 32|

|alan| 20|

+----+---+

通过Pandas中的DataFrame来创建DataFrame

import pandas as pd
pandas_df = pd.DataFrame([{'name':'liko','age':32},{'name':'alan','age':20}])
pandas_df.head()
spark.createDataFrame(pandas_df).show()

+---+----+

|age|name|

+---+----+

| 32|liko|

| 20|alan|

+---+----+

schema还可以用字符串名字:类型多个列用逗号分隔表示

l = [('liko', 23),('alan',20)]
rdd = sc.parallelize(l,3)
spark.createDataFrame(rdd, "a: string, b: int").show()

+----+---+

|   a|  b|

+----+---+

|liko| 23|

|alan| 20|

+----+---+

通过schema还可以指定字段类型,当指定的字段类型和自动推断出来的类型不一致时,会报错。
l = [('liko', 23), ('alan', 20)]
rdd = sc.parallelize(l, 3)
rdd = rdd.map(lambda row: row[1])
spark.createDataFrame(rdd, "int").show()

+-----+

|value|

+-----+

|   23|

|   20|

+-----+

实际类型为int类型,却指定为boolean

l = [('liko', 23), ('alan', 20)]
rdd = sc.parallelize(l, 3)
rdd = rdd.map(lambda row: row[1])
#spark.createDataFrame(rdd, "int").show()
spark.createDataFrame(rdd, "boolean").show()
TypeError: field value: BooleanType can not accept object 23 in type <class 'int'>

 

4.DataFramerdd一样可以通过读取文件,或者通过transformation转化得到。在

sparksessionread模块中有非常多的读取文件的方法,稍后后详细讲解,

transformation也会在后面讲解到。

通过read模块可以读取csv/jdbc/json/parquet/text等格式的文件。

print(dir(spark.read))

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_df', '_jreader', '_set_opts', '_spark', 'csv', 'format', 'jdbc', 'json', 'load', 'option', 'options', 'orc', 'parquet', 'schema', 'table', 'text']

5.newSession()这个方法会返回一个新的SparkSession,他们公用一个sparkcontext,但是注册的临时表,UDF这些是彼此隔离的。

spark1 = spark.newSession()
print(spark1 == spark)
conf = spark.conf
conf1 = spark1.conf
print(conf == conf1)
context = spark.sparkContext
context1 = spark1.sparkContext
print(context == context1)
udf = spark.udf
udf1 = spark1.udf
print(udf == udf1)

False

False

True

False

6.range(start, end=None, step=1, numPartitions=None)该方法创建的DataFrame,列标签为id,类型为pyspark.sql.types.LongTypenumPartitions用于指定分区数

df = spark.range(100,1000,37,3)
df.rdd.
getNumPartitions()
df.
show()

+---+

| id|

+---+

|100|

|137|

|174|

|211|

|248|

|285|

|322|

|359|

|396|

|433|

|470|

|507|

|544|

|581|

|618|

|655|

|692|

|729|

|766|

|803|

+---+

only showing top 20 rows

7.read 该方法返回 DataFrameReader对象,通过这个对象可以读取外部文件来创建

8.readStream 该方法返回DataStreamReader对象,该对象用于读取stream数据

9.sparkContext 返回底层的sparkContext对象

sc1 = spark.sparkContext

print(sc1.master)

local
10.sql(sqlQuery),使用SQL语句从表格或者视图中查询数据

df = spark.range(10,18,1,3)

df.show(8)

df.createOrReplaceTempView('test')

spark.sql('select * from test where id >= 13').show(5)

+---+

| id|

+---+

| 10|

| 11|

| 12|

| 13|

| 14|

| 15|

| 16|

| 17|

+---+

 

+---+

| id|

+---+

| 13|

| 14|

| 15|

| 16|

| 17|

+---+

11.stop()停止底层的sparkcontext

12.streams 返回StreamingQueryManager,该对象管理着在该sparksession中的所有StreamingQuery对象

13.table(tableName),使用一个表格的名字,返回该表格对应的DataFrame对象

df = spark.range(20)

df.createOrReplaceTempView('A')

spark.sql('select * from A where id > 10').show()

df1 = spark.table('A')

print(df.collect() == df1.collect())

| id|

+---+

| 11|

| 12|

| 13|

| 14|

| 15|

| 16|

| 17|

| 18|

| 19|

+---+

 

True
14.udf 返回UDFRegistration用于UDF函数的注册

print(spark.udf)

<pyspark.sql.udf.UDFRegistration object at 0x000002067E538DA0>

15.pyspark.sql.UDFRegistration(sqlContext),这个类正是用来注册用户自定义函数的类。这个类里面有一个最主要的方法,

register(name, f, returnType=StringType),第一个参数为自定义函数的名字,第二个参数f表示要传入的自定义的函数,函数里面定义了处理的逻辑,第三个关键字参数returnType用于定义返回值的类型,默认为StringType

下面我们定义一个求n次方的方法,方法名字叫pow1(m,n),接收两个参数m,n。要在pow方法中实现mn次方的计算,返回值为DoubleType.

from pyspark.sql.types import *



def pow1(m,n):

     return float(m)**float(n)



udf = spark.udf

udf.register('pow1',pow1,returnType=DoubleType())



df = spark.range(0,10,2,3)

df.createOrReplaceTempView('A')

spark.sql('select pow1(id,2) from A').show()

spark.sql('select pow1(id,3) from A').show()

+-----------+

|pow1(id, 2)|

+-----------+

|        0.0|

|        4.0|

|       16.0|

|       36.0|

|       64.0|

+-----------+

|pow1(id, 3)|

+-----------+

|        0.0|

|        8.0|

|       64.0|

|      216.0|

|      512.0|

+-----------+

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值