【Spark计算引擎----第四篇(SparkSQL)---《Spark SQL 介绍:DataFrame 的 Row 和 Schema,DataFrame 的创建与基本使用》】

前言:
💞💞大家好,我是书生♡,本阶段和大家一起分享和探索大数据技术Spark—SparkSQL,本篇文章主要讲述了:Spark SQL 介绍,DataFrame 的 Row 和 Schema,DataFrame 的创建与基本使用等等。欢迎大家一起探索讨论!!!
💞💞代码是你的画笔,创新是你的画布,用它们绘出属于你的精彩世界,不断挑战,无限可能!

个人主页⭐: 书生♡
gitee主页🙋‍♂:闲客
专栏主页💞:大数据开发
博客领域💥:大数据开发,java编程,前端,算法,Python
写作风格💞:超前知识点,干货,思路讲解,通俗易懂
支持博主💖:关注⭐,点赞、收藏⭐、留言💬

1. SparkSQL介绍

  Spark SQL 是 Apache Spark 中的一个模块,它为处理结构化和半结构化数据提供了一种高效且易用的方法。Spark SQL 允许用户通过 SQL 查询或通过 DataFrame 和 Dataset API 来处理数据。

定义:

  • SparkSQL是处理结构化数据的模块/组件
  • 结构化数据 -> 可以用schema描述的数据
    • 表格, 行列数据
    • DataFrame
    • DataSet
  • SparkSQL比Spark Core操作起来更加便捷, 提供更多高级API

特点

  • 融合性
    • 通过SQL语言和spark一起使用, SparkSQL还提供了DSL方式(将SQL的关键字以面向对象的编程思想使用)
  • 统一数据访问
    • 通过read方法读取各种数据源的数据, HDFS/MySQL/Redis/Hbase/Kafka/ElasticSearch/文件
    • 通过write方法将计算结果保存到各种数据源, HDFS/MySQL/Redis/Hbase/Kafka/ElasticSearch/文件
  • 标准数据连接
    • 各种工具通过odbc和jdbc方式连接SparkSQL
  • 兼容hive
    • 使用HiveSQL的方法
    • 读写Hive数据表数据

1.1 Spark SQL 的核心概念

  1. DataFrame:

    • DataFrame 是 Spark SQL 中的一个分布式数据集,它是一个由行和列组成的二维表格。
    • DataFrame 可以被看作是一个不可变的表格,其中每一列都是某种类型的值。
    • DataFrame API 提供了丰富的操作,包括选择、过滤、分组、聚合等。
  2. Dataset:

    • Dataset 是 DataFrame 的一个扩展,它支持强类型和编译时类型检查。
    • Dataset API 提供了类似于 DataFrame 的操作,但同时也支持更强大的类型安全性和表达能力。
  3. Row:

    • Row 是 DataFrame 中单行数据的表示形式,它提供了按列名访问数据的能力。
    • Row 类似于一个不可变的 JavaBean 对象,可以通过字段名访问数据。
  4. Schema:

    • Schema 描述了 DataFrame 的结构,包括每一列的名称和数据类型。
    • Schema 是 DataFrame 的元数据,它确保了数据的一致性和正确处理。

1.2 Spark SQL 的主要特性

  1. SQL 查询:

    • Spark SQL 支持使用标准 SQL 语法查询数据。
    • 可以注册 DataFrame 作为临时视图,然后使用 SQL 查询这些视图。
  2. 自动类型推断:

    • 当从外部数据源加载数据时,Spark SQL 可以自动推断数据的模式和类型。
    • 用户也可以手动指定数据模式。
  3. 数据源 API:

    • Spark SQL 提供了一个统一的 API 来读取和写入各种数据源,包括 CSV、JSON、Parquet、Avro、JDBC 等。
  4. 性能优化:

    • Spark SQL 使用 Catalyst 优化器来自动优化查询计划,提高执行效率。
    • 支持多种优化策略,如列式存储、缓存等。
  5. 交互式查询:

    • Spark SQL 可以在 Spark 的交互式环境中使用,如 Spark Shell 或 Jupyter Notebook。
    • 支持实时查询和结果反馈。

1.3 SparkSQL和HiveSQL对比

  • HiveSQL

    • Hive工具对HDFS文件数据映射成数据表, 同时提供了SQL编程方式
    • Hive的metastore服务管理表的元数据
    • Hive借助MapReduce计算引擎进行计算
  • Spark on Hive

    • SparkSQL只是用于处理结构化数据的计算引擎, 不存储数据, 所以表的元数据借助于Hive的metastore服务存储
    • SparkSQL借助catalyst引擎将SparkSQL转成Spark RDD进行计算
    • SparkSQL提供了SQL和DSL两种编程方式

1.4 数据类型

  • RDD
    • 弹性分布式数据集合
    • 可以存储任意结构数据 [], [[],[],[]], [[[],[]],[[],[]]] (存储二维的)
    • 只存储数据值
  • DataFrame
    • 弹性分布式数据集合
    • 只存储结构化数据
    • DF由row对象和schema对象组成的
      • row对象 -> 一行数据/RDD一个列表
      • schema对象 -> 表的元数据(表名/字段名/字段类型)
  • DataSet
    • java和scala编程语言中特有的数据类型
    • DataSet中一行数据就是一个DataFrame类型

Spark SQL 是一个强大的工具,它结合了 SQL 查询的易用性和 DataFrame API 的灵活性。通过 Spark SQL,开发者可以轻松地处理结构化和半结构化数据,执行复杂的查询和数据处理任务,同时保持较高的性能和效率。无论是用于数据科学项目还是生产环境中的数据处理,Spark SQL 都是一个值得信赖的选择。
在这里插入图片描述

2. DataFrame的row对象和schema对象操作

  在 Apache Spark 中,DataFrame 是一个分布式的、不可变的、带有 Schema 的数据集。DataFrame 可以被视为表格数据的一种表示,其中每一行是一个 Row 对象,每一列都有明确的数据类型。Row 对象和 Schema 对象是 DataFrame 的两个重要组成部分。

  • Row 对象
    Row 对象代表 DataFrame 中的一行数据。它是一个不可变的对象,提供了两种主要的方式来访问数据:通过索引和通过列名。
  • Schema 对象
    Schema 对象描述了 DataFrame 的结构,即每一列的名称和数据类型。Schema 是 DataFrame 的元数据,对于确保数据的一致性和正确处理至关重要。

2.1 ROW对象

我们的row对象是来自类,来自于pyspark.sql

# dataframe是由row对象和schema对象组成
# 导入row对象的类
from pyspark.sql import Row

创建一个ROW对象,一行数据就是一个ROW对象
对象名= 类名属性值()

row1 = Row(name='小明', age=18, gender='男') #指定了列名
row2 = Row('小红', 16, '女')

查看row数据

row1 = Row(name='小明', age=18, gender='男')
row2 = Row('小红', 16, '女')
print(row1)
print(row2)
print(type(row1))
print(type(row2))

在这里插入图片描述

可以发现我们在创建ROW对象的时候,指定列名和不指定,输出数据的格式是有差异的!!!
建议:如果要创建ROW对象的话,使用第一种方法。加上列名会更清晰

获取ROW对象的属性值

获取属性的方式,跟我们的python差不多,可以根据下标,和属性名去获取对应的值

  • 对象名.属性名
  • 对象名['属性名']
  • 对象名[下标]
# 对象名.属性名
print(row1.name)
print(row1.age)
# 对象名[属性名]
print(row1['gender'])
print(row1[0])
print(row1[1])
print(row1[2])
print("")
# 对象名[下标]
print(row2[0])
print(row2[1])
print(row2[2])

注意:第一种创建方式我们可以通过属性名获取对应的值,但是第二种方式没有属性名,那么就只能通过下标进行获取对应下标的值。

2.2 schema对象

我们需要导入schema对象的各种数据类型类

# 导入schema对象的各种数据类型类
from pyspark.sql.types import *
  • StructType()类创建schema对象调用add方法 创建Schema

创建schema对象 表结构->字段名,字段类型
对象名=类名(属性值) 通过StructType()类创建schema对象,
调用add方法添加字段名/字段类型/是否允许为空(默认True)
StringType()->字符串类型的类
IntegerType()->整数类型的类
nullable ->决定是否可以为空

schema1 = (StructType().
		   add(field='name', data_type=StringType(), nullable=True).
		   add('age', IntegerType(), nullable=False).
		   add('gender', StringType()))

我们可以通过下标来获取对应的类名

print(schema1)
print(type(schema1))
# 获取对象属性
# 获取第一个字段信息
print(schema1[0])
print(schema1[1])
print(schema1[2])

在这里插入图片描述

  • 通过list创建schema对象

scheme3 = StructType(fields=[StructField('name',StringType(),True),
							 StructField('age',IntegerType(),False),
							 StructField('gender',StringType())])

在这里插入图片描述

3. DataFrame的创建

DataFrame是由SparkSession类的对象提供的方法进行创建

SparkSession就是df的入口类, SparkSession在SparkContext类基础进行进一步封装

3.1 DataFrame的创建方式

在 Apache Spark 中,DataFrame 是一种非常重要的数据结构,它是一个分布式的、不可变的表格型数据集,具有明确的
Schema。DataFrame 可以通过多种方式创建

  • 从 RDD 创建 DataFrame

如果已经有了一个 RDD,可以使用 toDF() 方法将其转换为 DataFrame。需要注意的是,如果 RDD 中的元素是一个 tuple,那么 Spark 会自动推断出列名;如果需要指定列名,则可以在调用 toDF() 方法时传入列名列表。

示例代码

from pyspark.sql import SparkSession

# 创建 SparkSession
spark = SparkSession.builder \
    .appName("DataFrame Creation") \
    .getOrCreate()

# 创建一个 RDD
data_rdd = spark.sparkContext.parallelize([
    ("Alice", 25, "NY"),
    ("Bob", 30, "LA"),
    ("Charlie", 22, "Chicago")
])

# 从 RDD 创建 DataFrame
df_from_rdd = data_rdd.toDF(["name", "age", "city"])

# 显示 DataFrame
df_from_rdd.show()
  • 从外部数据源创建 DataFrame

Spark 支持从多种外部数据源创建 DataFrame,包括 CSV、JSON、Parquet、Avro 等格式的文件。

示例代码

# 从 CSV 文件创建 DataFrame
df_from_csv = spark.read.format("csv").option("header", "true").load("path/to/data.csv")

# 从 JSON 文件创建 DataFrame
df_from_json = spark.read.json("path/to/data.json")

# 从 Parquet 文件创建 DataFrame
df_from_parquet = spark.read.parquet("path/to/data.parquet")
  • 从 Python 字典创建 DataFrame

如果数据以字典的形式存在,可以使用 createDataFrame 方法创建 DataFrame。

示例代码

# 创建数据字典
data_dict = {
    "name": ["Alice", "Bob", "Charlie"],
    "age": [25, 30, 22],
    "city": ["NY", "LA", "Chicago"]
}

# 从字典创建 DataFrame
df_from_dict = spark.createDataFrame(data_dict)

# 显示 DataFrame
df_from_dict.show()
  • 从 NumPy 数组或 Pandas DataFrame 创建 DataFrame

如果您的数据是以 NumPy 数组或 Pandas DataFrame 的形式存在,您可以通过以下方式将其转换为 Spark DataFrame。

示例代码

import pandas as pd
import numpy as np

# 创建 Pandas DataFrame
pandas_df = pd.DataFrame({
    "name": ["Alice", "Bob", "Charlie"],
    "age": [25, 30, 22],
    "city": ["NY", "LA", "Chicago"]
})

# 从 Pandas DataFrame 创建 Spark DataFrame
df_from_pandas = spark.createDataFrame(pandas_df)

# 从 NumPy 数组创建 Pandas DataFrame,再转换为 Spark DataFrame
numpy_array = np.array([
    ["Alice", 25, "NY"],
    ["Bob", 30, "LA"],
    ["Charlie", 22, "Chicago"]
])
pandas_df_from_numpy = pd.DataFrame(numpy_array, columns=["name", "age", "city"])
df_from_numpy = spark.createDataFrame(pandas_df_from_numpy)

# 显示 DataFrame
df_from_pandas.show()
df_from_numpy.show()
  • 从现有 DataFrame 创建新的 DataFrame

可以使用现有的 DataFrame 通过选择、过滤、重命名列等方式创建新的 DataFrame。

示例代码

# 创建原始 DataFrame
original_df = spark.createDataFrame([
    ("Alice", 25, "NY"),
    ("Bob", 30, "LA"),
    ("Charlie", 22, "Chicago")
], ["name", "age", "city"])

# 从现有 DataFrame 创建新的 DataFrame
selected_df = original_df.select("name", "age")
filtered_df = original_df.where(original_df.age > 25)
renamed_df = original_df.withColumnRenamed("age", "years_old")

# 显示 DataFrame
selected_df.show()
filtered_df.show()
renamed_df.show()
  • 从手动定义的 Schema 创建 DataFrame

如果数据源没有自带 Schema,可以手动定义 Schema 并创建 DataFrame。

示例代码

from pyspark.sql.types import StructType, StructField, StringType, IntegerType

# 定义 Schema
schema = StructType([
    StructField("name", StringType(), True),
    StructField("age", IntegerType(), True),
    StructField("city", StringType(), True)
])

# 从 RDD 创建 DataFrame 并指定 Schema
data_rdd = spark.sparkContext.parallelize([
    ("Alice", 25, "NY"),
    ("Bob", 30, "LA"),
    ("Charlie", 22, "Chicago")
])
df_with_schema = spark.createDataFrame(data_rdd, schema)

# 显示 DataFrame
df_with_schema.show()

示例完整代码

这里是一个完整的示例代码,展示了如何从不同的数据源创建 DataFrame:

from pyspark.sql import SparkSession
import pandas as pd
import numpy as np
from pyspark.sql.types import StructType, StructField, StringType, IntegerType

# 创建 SparkSession
spark = SparkSession.builder \
    .appName("DataFrame Creation") \
    .getOrCreate()

# 从 RDD 创建 DataFrame
data_rdd = spark.sparkContext.parallelize([
    ("Alice", 25, "NY"),
    ("Bob", 30, "LA"),
    ("Charlie", 22, "Chicago")
])
df_from_rdd = data_rdd.toDF(["name", "age", "city"])
df_from_rdd.show()

# 从 CSV 文件创建 DataFrame
df_from_csv = spark.read.format("csv").option("header", "true").load("path/to/data.csv")
df_from_csv.show()

# 从 JSON 文件创建 DataFrame
df_from_json = spark.read.json("path/to/data.json")
df_from_json.show()

# 从 Parquet 文件创建 DataFrame
df_from_parquet = spark.read.parquet("path/to/data.parquet")
df_from_parquet.show()

# 从 Python 字典创建 DataFrame
data_dict = {
    "name": ["Alice", "Bob", "Charlie"],
    "age": [25, 30, 22],
    "city": ["NY", "LA", "Chicago"]
}
df_from_dict = spark.createDataFrame(data_dict)
df_from_dict.show()

# 从 Pandas DataFrame 创建 Spark DataFrame
pandas_df = pd.DataFrame({
    "name": ["Alice", "Bob", "Charlie"],
    "age": [25, 30, 22],
    "city": ["NY", "LA", "Chicago"]
})
df_from_pandas = spark.createDataFrame(pandas_df)
df_from_pandas.show()

# 从 NumPy 数组创建 Pandas DataFrame,再转换为 Spark DataFrame
numpy_array = np.array([
    ["Alice", 25, "NY"],
    ["Bob", 30, "LA"],
    ["Charlie", 22, "Chicago"]
])
pandas_df_from_numpy = pd.DataFrame(numpy_array, columns=["name", "age", "city"])
df_from_numpy = spark.createDataFrame(pandas_df_from_numpy)
df_from_numpy.show()

# 从手动定义的 Schema 创建 DataFrame
schema = StructType([
    StructField("name", StringType(), True),
    StructField("age", IntegerType(), True),
    StructField("city", StringType(), True)
])
df_with_schema = spark.createDataFrame(data_rdd, schema)
df_with_schema.show()

# 从现有 DataFrame 创建新的 DataFrame
original_df = spark.createDataFrame([
    ("Alice", 25, "NY"),
    ("Bob", 30, "LA"),
    ("Charlie", 22, "Chicago")
], ["name", "age", "city"])

selected_df = original_df.select("name", "age")
filtered_df = original_df.where(original_df.age > 25)
renamed_df = original_df.withColumnRenamed("age", "years_old")

selected_df.show()
filtered_df.show()
renamed_df.show()

# 关闭 SparkSession
spark.stop()

3.2 DataFrame基本的创建方式

我们DataFrame最基本的创建方式就是通过 sparksession类中的createDataFrame方法来创建DataFrame对象
创建格式:
sparksession.createDataFrame(data=, schema=)

注意:

  • data的数据一定是二维数据 [[],[],[]]
  • schema对象的数据类型和数据一致, 有几列数据就需要有几个数据类型

因为我们的DataFrame包含ROW和Schema 两个 ,因此我们需要创建祥这两个

  1. 导入相关的包 一会创建ROW对象和Schema对象
  • 创建ROW我们使用字段名:字段值
  • 创建Schema我们使用add方法
from pyspark.sql import Row
from pyspark.sql.types import *
from pyspark.sql import SparkSession

# 创建row对象, 一行数据就是一个row对象
row1 = Row(id=1, name='小明', age=18)
row2 = Row(id=2, name='小红', age=16)
# 创建schema对象
schema = StructType(). \
	add('id', IntegerType(), False). \
	add('name', StringType()). \
	add('age', IntegerType())
  1. df是由SparkSession类的对象提供的方法进行创建,因此需要先创建sparksession对象,需要通过SparkSession类来创建,使用其中的builder属性去访问getOrCreate()方法

创建sparksession对象
SparkSession.builder: 获取类的属性(类名.类属性名), 返回Builder类的对象
Builder类的对象提供了一个getOrCreate方法, 可以返回sparksession对象

spark = SparkSession.builder.getOrCreate()
  1. 通过sparksession调用createDataFrame方法创建DataFrame对象
# 创建dataframe对象
# data是二维数据
# 因为df是一个二维对象,我们的row只是一行数据,所以我们需要使用【】将我们的row对象封装起来,哪怕只有一个row对象,一样也需要使用【】封装起来
df1 = spark.createDataFrame(data=[row1,row2], schema=schema)
# 哪怕只有一个row对象,一样也需要使用【】封装起来
df1 = spark.createDataFrame(data=[row1], schema=schema)
# 'id int,name string,age int'->字段名1 字段类型1,字段名2 字段类型2,...
# 我们也可以不在上面创建Schema,可以在创建的时候直接指定列名
df1 = spark.createDataFrame(data=[row1, row2], schema='id int,name string,age int')

查看数据,以及表的结构

print(df1)  # 直接打印df对象,显示的是df的字段名和字段类型
print(type(df1))
# 查看df的数据
df1.show()
# 查看df的表结构
df1.printSchema()

在这里插入图片描述

3.3 RDD转换成DF

RDD的数据结构是二维数据, 才能转换成df
df转换成RDD后, RDD中的每个元素是每个row对象(df中一行数据就是一个row对象)

创建格式:此时的data不再Row,而是一个RDD对象
sparksession.createDataFrame(data=, schema=)

  • 创建sparksession对象
# 创建sparksession对象
spark = SparkSession.builder.getOrCreate()
  • 创建sc对象,因为我们要创建一个RDD对象,因此要创建sc。

此时的sc不是从SparkContext直接创建的,而是通过sparksession类,SparkSession类是在SparkContext的基础上进行了封装,也就是SparkSession类中包含了SparkContext,因此我们通过sparksession对象调用里面的sparkContext来创建sc对象
sparkContext 被 @property装饰器装饰 ,调用时不需要加括号

# 创建sparkcontext对象
# 通过@property装饰器装饰的方法在调用时不需要加括号
sc = spark.sparkContext

创建一个二维的RDD对象,因为df是二维的


# 创建rdd对象
rdd1 = sc.parallelize(c=[[1, '小明', 18],
						 [2, '小红', 20],
						 [3, '小王', 33]])

创建Schema对象

# rdd对象转化成df对象, 通过rdd对象的toDF算子
schema = (StructType().
		  add('id', IntegerType(), False).
		  add('name', StringType()).
		  add('age', IntegerType()))
  1. 创建DF对象通过createDataFrame方法吗,此时的data要传入一个RDD对象
# 通过createDataFrame方法创建df对象
df1 = spark.createDataFrame(data=rdd1, schema=['id', 'name', 'age'])
df1.show()
df2 = spark.createDataFrame(data=rdd1, schema=schema)
df2.show()
  1. 通过RDD对象调用toDF方法创建对象
# rdd对象转化成df对象, 通过rdd对象的toDF算子
df3 = rdd1.toDF(schema=schema)
df3.show()

3.4 DF对象转化成RDD对象

通过 DF对象调用rdd()方法转化成为RDD对象

# df对象转化成rdd对象
# 通过@property装饰器装饰的方法在调用时不需要加括号
new_rdd = df.rdd

获取RDD对应的值

# df中的一行数据就是一个row对象 Row(id=1, name='小明', age=18)
new_name = new_rdd.map(lambda x:(x[0],x[1],x[2]))
print(new_name.collect())
# x->Row(id=1, name='小明', age=18) row对象类型
# x.name->对象名.属性名
new_all= new_rdd.map(lambda x:(x.id,x.name,x.age))
print(new_all.collect())

在这里插入图片描述

5. DataFrame基本使用

SparkSQL提供了两种编写代码的方式

  • SQL方式
  • DSL方式

5.1 DSL方法 – DataFrame方法

spark提供DSL方法和sql的关键词一样,使用此方式和sql基本类似,在进行数据处理时,要按照sql的执行顺序去思考如何处理数据

from  join    知道数据在哪   df本身就是要处理的数据  df.join(df2)

where         过滤需要处理的数据   df.join(df2).where()

group by 聚合  数据的计算     df.join(df2).where().groupby().sum()

having        计算后的数据进行过滤 df.join(df2).where().groupby().sum().where()

select        展示数据的字段  df.join(df2).where().groupby().sum().where().select()

order by      展示数据的排序  df.join(df2).where().groupby().sum().where().select().orderBy()

limit         展示数据的数量 df.join(df2).where().groupby().sum().where().select().orderBy().limit()

------

DSL方法执行完成后会得到一个处理后的新df

数据准备:创建一个RDD对象,并且通过map算子分割成二维的结构,通过toDF方法,转换成DF对象,我们的schema采用的是直接定义的方法

# 使用DF的DSL方法实现对df数据处理
# DF的数据是结构化数据,所以DSL方法和SQL的关键字基本一致
from pyspark.sql import SparkSession

# 创建SparkSession对象
ss = SparkSession.builder.getOrCreate()

# 使用sparkcontext读取hdfs上的文件数据
sc = ss.sparkContext
# 将读取的文件数据转化为rdd
rdd = sc.textFile('hdfs://node1:8020/data/stu.txt')
res1 = rdd.collect()
# print(f'rdd文件数据:{res1}')
# 将每行字符串数据切割转为二维rdd
rdd_split = rdd.map(lambda x: x.split(','))
res2 = rdd_split.collect()
# print(f'切割后的rdd数据:{res2}')

# 将rdd转为df数据
df = rdd_split.toDF(
    schema='id string,name string,gender string,age string,birthday string,major string,hobby string,create_time string')
# 查看转化的df数据
df.show()

5.1.1 select操作 – 查询数据

  • 对象名.select(‘*’) --查询全部数据
  • 对象名.select(’字段名‘ / df.字段名 / df[‘字段名’]) 查询指定字段
  • 通过alias方法,-- 修改字段名称 --------》 df.字段名 / df[‘字段名’] 可以这么修改 ,’字段名‘ 不能这么修改
  • cast(类型)->字段对象的方法 修改字段类型,--------》 df.字段名 / df[‘字段名’] 可以这么修改 ,’字段名‘ 不能这么修改
  • selectExpr(‘字段表达式’) — selectExpr 修改字段类型
print('-------------------select操作-----------------------')
# select('*') 查询全部信息
de_select = df.select('*')
de_select.show()
# select(’字段名‘ / df.字段名 / df['字段名']) 查询指定字段
df_select1 = df.select('id',df.name,df['gender'])
df_select1.show()
# 修改字段名 .alias('新字段名')
print('-------------------select 修改字段名称操作-----------------------')
# 注意 :只有df.字段名 / df['字段名'] 可以这么修改 ,’字段名‘ 不能这么修改
df_select2 = df.select('id',df.name.alias('new_name'),df['gender'].alias('new_gender'))
df_select2.show()
print('-------------------select 修改字段类型操作-----------------------')
# cast(类型)->字段对象的方法
# astype(类型)->底层调用的cast方法
# 注意 :只有 df.字段名 / df['字段名'] 可以这么修改 ,’字段名‘ 不能这么修改
df_select3 = df.select('id',df.name.cast('string'),df['age'].cast("int"))
df_select3.show()
# 查看字段类型
df_select3.printSchema()
print('-------------------selectExpr 修改字段类型操作-----------------------')
# selectExpr('字段表达式')
df_selectExpr = df.selectExpr('cast(id as int)','name','gender as sex')
df_selectExpr.show()
df_selectExpr.printSchema()

df_select4 = df.select(df.id.cast('int'),df.name.cast('string'),df['age'].cast("int"),df.gender,df.major)
df_select4.show()

查询全部数据(show默认只显示20 条数据)
在这里插入图片描述
指定字段
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.1.2 where 操作 – 条件判断

我们的DSL条件查询有两种方法:

  • where()
  • filter()

使用方法:

  • 单个条件 ---- 对象名.where(条件)
  • 多个条件 ---- where 内部使用 and–> & , or —>| , not —> ~ 连接 查询条件
print('-------------------where 操作-----------------------')
# df.filter()等价于 df.where()
df_where = df.where('age>20').where('age<30').limit(5)
df_where.show()
df_where1= df.where(df.gender == '男')
df_where1.show()
df_where2= df.where('gender ="男"').limit(5)
df_where2.show()
print("---------------多个条件---------------------------")
# 多个条件 使用and or not
df_where3 = df.where('age>20 and gender=="男"')
df_where3.show()
# 多个条件 不再字符里面,必须要使用()括起来
# (条件1) & (条件二) and--> & , or --->| , not ---> ~
df_where4 = df.where((df.age > 22) & (df.gender == '男'))
df_where4.show()

多个条件 ,在同一个字符串里面 使用 and or not
多个条件 不再字符里面,必须要使用()括起来
(条件1) & (条件二) and–> & , or —>| , not —> ~

在这里插入图片描述

5.1.3 groupBy 操作 – 分组聚合

df.groupby() 等价于 df.groupBy()

print('-------------------groupBy 操作-----------------------')
# df.groupby() 等价于 df.groupBy()
# 对一列分组
# select gender, avg(age) from df group by gender
df_groupby1 = df_select4.groupBy('gender').avg('age')
df_groupby1.select('gender', df_groupby1['avg(age)'].alias('avg_age')).show()
df_groupby1.show()
# 对多列分组
df_groupby2 = df_select4.groupby('gender', 'major').avg('age')
df_groupby2.show()
# 分组聚合后再进行过滤
# select gender,major avg(age) from df group by gender,major having avg(age)>21.5
df_groupby3 = df_select4.groupby('gender', 'major').avg('age').where('avg(age)>21.5')
df_groupby3.show()

有几个分组字段,就在groupBy() 括号里面写几个分组字段,字段需要使用单引号引起来,这字段之间使用英文逗号分隔
分组之后可以直接紧跟着我们的聚合方法 求最大值,求和,平均值等等。
聚合方法 只能紧跟在groupby操作之后

在这里插入图片描述

5.1.4 orderby 操作 – 排序

orderby 操作,可以指定字段进行排序,默认为TRUE是升序,可以指定为False 降序
可指定一个或者多个字段 ,一个字段的话,可以不写排序规则,如果多个字段进行排序,必须使用ascending进行指定的排序规则,并且 要使用 【】将没也给字段的排序规则都指定出来 —》 ascending=[True,False]
我们也可以使用df_select4.age.desc(),df_select4.id.asc() 通过desc和asc来指定排序规则

print('-------------------orderby 操作-----------------------')
# df.orderby() 等价于 df.sort()
# 默认是升序,TrUE是升序,FALSE是降序
df_orderby = df_select4.orderBy('age',ascending=False).limit(5)
df_orderby.show()
df_orderby1 = df_select4.orderBy('age',ascending=True).limit(5)
df_orderby1.show()
df_orderby2 = df_select4.orderBy(['age','id'],ascending=[True,False]).limit(5)
df_orderby2.show()
df_orderby3 = df_select4.orderBy(df_select4.age.desc(),df_select4.id.asc()).limit(5)
df_orderby3.show()
df_orderby3 = df_select4.orderBy(df_select4['age'].desc(),df_select4['id'].asc()).limit(5)
df_orderby3.show()

在这里插入图片描述

5.1.5 limit 操作 – 限制显示的数据条数

limit:限制df的条目数, 新的df只能有limit指定条目数的行
show:展示指定条目数的df行, df可以很多行数据,只是展示指定条目数的行数据
show:默认展示20条数据, 可以通过n参数设置展示条目数; truncate参数默认是True, 是否取消显示省略

print('-------------------limit 操作-----------------------')
"""
limit:限制df的条目数, 新的df只能有limit指定条目数的行
show:展示指定条目数的df行, df可以很多行数据,只是展示指定条目数的行数据
show:默认展示20条数据, 可以通过n参数设置展示条目数; truncate参数默认是True, 是否取消显示省略
"""
df_limit = df_select4.limit(num=5)
df_limit.show()

在这里插入图片描述

5.1.6 withColum 操作 --添加新字段

withColumn(‘新字段名’,‘原字段名的计算’) 添加一个新的字段,在原本的字段上进行操作
withColumn(‘new_age’,lit(10)) 添加一个常数列 ,需要导入一个类 使用lit()方法

print('-------------------withColum 操作-----------------------')
# 在df的末尾数据中添加新字段
# df.withColumn('新字段名','原字段名的计算')
de_withColum = df_select4.withColumn('age2',df_select4.age+10)
de_withColum.show()
# 等价于
df_select4.select('*',df_select4.age+10).show()
# 在df的末尾数据中添加常数列
from pyspark.sql.functions import  lit
de_withColum1 = df_select4.withColumn('new_age',lit(10)).limit(5).show()

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值