pyspark详细讲解

spark概念

Apache Spark是用于大规模数据(large-scala data)处理的统一(unified)分析引擎。

简而言之,spark是一款分布式的计算框架,用于调度成千上万的服务器集群,计算TB、PB乃至EB级别的海量数据

spark支持众多的编程语言进行开发,而python语言,则是spark的重点支持的方向。

pyspark是spark官方开发的python语言第三方库。

pyspark基础使用:

安装pyspark 包在命令提示符中 pip install --version

首先需要一个执行代码环境的入口对象:类 SparkContext的类对象

打开pycharm 基础示范:

#第一步 导包
from pyspark import SparkConf,SparkContext
# 创建SparkConf类对象,服务器入口,执行环境的入口对象
conf = SparkConf().setMaster("local[*]").setAppName("test_spark、")
#上一行为链式结构,
#与下面三行作用相同
"""
conf = SparkConf()
conf.setMaster("local[*]")#服务器为本机或者是数据集群
conf.setAppName("test_spark_app")#程序的名字"""

#基于SparkConf类对象创建SparkContext类对象,服务器入口,执行环境的入口对象
sc = SparkContext(conf=conf)#pyspark代码写入的入口,连接集群和驱动代码
#打印Pyspark版本
print(sc.version)
#停止Pyspark程序运行
sc.stop()#关闭入口

结果为:

你所下载的pyspark第三包的版本

数据输入

RDD(弹性分布式数据集 Resilient Distributed Datassets)对象

SparkContext类对象是pyspark编程所有功能的入口,相当店铺的门,打开后才能进行售卖,制作

数据输入:

通过SparkContext类对象的成员方法完成数据的读取操作,读取后得到RDD类对象,

挑选原材料

数据处理计算:

通过RDD类对象的成员方法完成各种数据计算的需求,将原材做成面,蛋糕等成品

数据输出:

将处理完成后的RDD对象调用各种成员方法完成写出文件、转换为list等操作

相当于打包售卖

让我们来使用一下rdd对象来感受一下吧

# 导包
from pyspark import SparkConf,SparkContext
# 创建SparkConf类对象连接服务器,设置配置
conf = SparkConf().setMaster("local[*]").setAppName("test_spark_app")
#基于SparkConf类对象创建SparkContext类对象,服务器入口,执行环境的入口对象
sc = SparkContext(conf=conf)

# parallelize(数据容器)转化为RDD数据
rdd1 = sc.parallelize([123,"hello",56])
rdd2 = sc.parallelize((1,2,456))
rdd3 = sc.parallelize("hello word")
rdd4 = sc.parallelize({123,"jane",67})
rdd5 = sc.parallelize({'key1': 50,'key2':60})

# collect()收集数据
print(rdd1.collect())#[123, 'hello', 56]
print(rdd2.collect())#[1, 2, 456]
print(rdd3.collect())#['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'd']
print(rdd4.collect())#[123, 67, 'jane']
print(rdd5.collect())#['key1', 'key2']

# 通过textFile将本地文件转化为RDD对象
rdd =sc.textFile("D:\Hello.txt")

print(rdd.collect())#['Hello world!', 'Meet you to nice!']
#停止Pyspark程序运行
sc.stop()

此为hello.txt文件内容:

数据计算

map()

将RDD 数据一条条处理(处理逻辑取决于map接收的处理函数),返回新的rdd

语法:

rdd.map(func)

func(): (T) -->U

():传入参数,(T):传入一个参数

-->U :返回值

(T)-->U:传入一个任意类型的参数,返回一个返回值,类型不限

(A) -->A:传入一个任意类型的参数,返回一个同类型参数

from pyspark import SparkConf,SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf=SparkConf().setMaster("local[*]").setAppName("text_spark_app")
sc =SparkContext(conf=conf)
rdd = sc.parallelize([1,2,3,4,5])
#map(func)传入参数为函数,rdd中的每一个数据都会执行func函数,返回RDD对象
# 且func()是传入参数为T 而返回值为U,两者不同且存在
rdd = rdd.map(lambda x:x*10)
print(rdd.collect())#[10,20,30,40,50]
sc.stop()
如果以上map()代码出现这种报错情况:

并且为python3.13版本的,是由于pyspark与该版本不兼容,不能支持python3.13,

解决办法:
1.降低python版本
2.安装虚拟环境anaconda,在虚拟环境中安装python版本:
建议安装3.10
记得查询pyspark与哪个版本python兼容

flatMap()

rdd执行map操作,然后进行解除嵌套操作:

​
from pyspark import SparkContext,SparkConf
import os
os.environ['PYSPARK_PYTHON'] ="D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("text_spark_app")
sc = SparkConftext(conf = conf)

#准备一个rdd
rdd = sc.parallelize(["itheima itcast 666","itheima itheima itcast","python itheima"])
rdd = rdd.map(lambda x: x.split())
print(rdd.collect())#[["itheima","itcast","666"],["itheima","itheima","itcast"],["python","itheima"]]

#将单词逐个取出,逐个封装到列表中
rdd = rdd.flatMap(lambda x: x.split())
print(rdd.collect())#["itheima","itcast","666","itheima","itheima","itcast","python","itheima"]

#关闭入口
​sc.stop()

reduceByKey()

针对KV型(->二元元组,即(10,"it"))RDD,

自动按key(二元元组的第一个元素)分组

然后根据你提供的聚合限制,完

成组内数据value(二元元组的第二个元素)的聚合操作

语法:

rdd.reduceByKey(func)

func:(v,v) ->v 传入两个返回一个,类型相等

代码实现:

from pyspark import SparkConf,SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_app")
sc = SparkContext(conf = conf)

rdd = sc.parallelize([('a',1),('b',5),('a',5),('b',9)])

#以元组的第一个进行分组,以第二元素进行相加
rdd = rdd.reduceByKey(lambda a,b:a+b)

print(rdd.collect())
#[('b', 14), ('a', 6)]
sc.stop()#关闭入口

filter()

功能:过滤想要的数据进行保留

语法:

rdd.filter(func)

函数类型 func: (T) --> bool

传入参数T,返回值必须是bool类型:True or False

而返回值为True的将会被保留

from pyspark import SparkConf,SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_app")
sc = SparkContext(conf = conf)
#准备一个rdd对象
rdd = sc.parallelize([1,2,3,4,5])
#filter筛选偶数,返回值True的保留
rdd = rdd.filter(lambda num: num%2==0)#返回值为num%2==0,逻辑判断语句返回的是True/False
print(rdd.collect())#result:[2, 4]
sc.stop()

distinct()

对RDD数据进行去重,返回新的RDD

语法:

rdd.distinct() 无需传参

from pyspark import SparkConf,SparkContext
import os
#准备入口环境
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_app")
sc =SparkContext(conf = conf)
#准备一个rdd数据
rdd=sc.parallelize([1,2,1,4,2,54,6,45,75,3,24,5,6,4,6])
#将rdd数据去重
rdd = rdd.distinct()
print(rdd.collect())#result:[24, 1, 2, 75, 3, 4, 5, 54, 6, 45]
sc.stop()#关闭入口

sortBy()

对RDD数据进行排序,基于你指定的排序依据

语法:

rdd.sortBy(func ,ascending = False ,numPartitions=1)

func:(T)-->U:须告知按照rdd中的哪个数据,进行排序,比如lambda x:x[1],代表rdd中的第二列元素进行排序

ascending:True升序(默认值),False降序

numPartitions:用几个分区排序,numPartitions=1

from pyspark import SparkConf,SparkContext
import os
#准备入口环境
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_app")
sc =SparkContext(conf = conf)
#准备一个rdd对象
rdd=sc.parallelize([('itcast', 4), ('python', 6), ('itheima', 7), ('spark', 4), ('pyspark', 3)])
#列表中每一个元组的的第二个元素为根据,进行排序
sor_rdd = rdd.sortBy(lambda x:x[1],ascending=True,numPartitions=1)
print(sort_rdd.collect())#result:[('pyspark', 3), ('itcast', 4), ('spark', 4), ('python', 6), ('itheima', 7)]
# 关闭入口
sc.stop()

数据输出

collect()

将RDD各个分区内的数据,统一收集到Driver中,形成一个List对象

语法:

rdd.collect() 返回值是一个list

from pyspark import SparkConf,SparkContext
import os
#准备入口环境
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_app")
sc = SparkContext(conf = conf)
#准备一个rdd对象
rdd = sc.parallelize([1,2,3,4,5])
print(rdd)
#输出的是一个RDD类对象名
# result:ParallelCollectionRDD[0] at readRDDFromFile at PythonRDD.scala:289
print(rdd.collect())
# result:[1, 2, 3, 4, 5]
sc.stop()#关闭入口

reduce()

对RDD数据集按照你传入的逻辑进行聚合

语法:

rdd.reduce(func)

func:(T,T) --> T

from pyspark import SparkConf,SparkContext
import os
#准备入口环境
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_app")
sc = SparkContext(conf = conf)
#准备一个rdd对象,1~9数字
rdd = sc.parallelize(range(1,10))
#逐个取出rdd数据,reduce聚合处理
print(rdd.reduce(lambda a,b:a+b))
sc.stop()#关闭入口

lambda a,b:a+b内部计算大致过程:

take()

取RDD的前N个元素,组合成list返回法:

语法:

rdd.take()

from pyspark import SparkConf,SparkContext
import os
#准备入口环境
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_app")
sc = SparkContext(conf = conf)
# 准备一个RDD对象
rdd = sc.parallelize([32,263,4,5,8,120])
#take()取走前三个数据,返回存储在一个列表中
take_list = rdd.take(3)
print(take_list)
# result:[32, 263, 4]
sc.stop()#关闭入口

count()

计算RDD 中有多少条数据,返回值为一个数字

语法:

rdd.count()

from pyspark import SparkConf,SparkContext
import os
#准备入口环境
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_app")
sc = SparkContext(conf = conf)
# 准备一个RDD对象
rdd = sc.parallelize([32,263,4,5,8,120])
# 计算RDD中有多少数据
count = rdd.count()
print(count)
#result:6
sc.stop()#关闭入口

savaAsTextFile()

将RDD数据写入文本文件中

注意:文本文件的路径名字在未运行前需不存在

from pyspark import SparkConf,SparkContext
import os
#准备入口环境
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_app")
sc = SparkContext(conf = conf)
# 准备一个RDD对象
rdd = sc.parallelize([32,263,4,5,8,120])
# 将RDD数据存储到文件
rdd.saveAsTextFile("D:/output1")
sc.stop()
如果出现问题:

原因:调用保存文件的savaAsTextFile(),需要配置Hadoop依赖

1.下载winutils.exe:https://codeload.github.com/cdarlint/winutils/zip/refs/heads/master

2.配置环境变量:

搜索:高级系统设置:

点击框选

点击环境变量

下一步:

下一步:

点击path这一行

点击新建

在输入框中填入以下内容:

最后连续点击三个确认.

之后再次运行上述代码,会在D盘文件中出现output1文件

打开后:

有很多文件这就表明当前的RDD有多个分区,

原因:saveAsTextFile()输出文件的个数是由RDD的分区决定的。

假如有24个文件,这表明有24分区

电脑CPU有多少核心数就默认有多少分区,

rdd数据会均匀的分散到各个分区去存储,

输出文件有的是空的,有的是列表中数据元素

将RDD分区修改为1个

方法一

SparkConf对象设置属性全局并行度为1:

conf = SparkConf().setMaster("local[*]").setAppName("test_app") 

conf.set("spark.default.parallelism",1) sc =SparkContext(conf = conf)

sc = SparkContext(conf = conf)

方法二

创建RDD对象时设置(parallelize方法传入numSlices参数为1):

rdd=sc.parallelize([32,263,4,5,8,120],1)

 or:

rdd=sc.parallelize([32,263,4,5,8,120],numSlices=1)

加入以上方法之一以后的代码和运行结果:

from pyspark import SparkConf,SparkContext
import os
#准备入口环境
os.environ['PYSPARK_PYTHON'] = "D:conda/envs/myenv/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_app")
conf.set("spark.default.parallelism",1)
sc = SparkContext(conf = conf)
# 准备一个RDD对象,设置分区为1
rdd = sc.parallelize([32,263,4,5,8,120],1)
# 将RDD数据存储到文件
rdd.saveAsTextFile("D:/output2")
sc.stop()#关闭入口

        D:/output2文件的内容

 part-00000的内容:

### 关于 PySpark 的教程、入门指南以及使用示例 以下是有关 PySpark详细介绍,涵盖了安装、基本操作和 WordCount 范例等内容。 #### 安装 PySpark PySpark 是 Apache Spark 提供的一个 Python 接口,用于大数据处理。为了在本地环境中运行 PySpark,可以按照以下方式完成安装[^1]: - 首先下载并解压 Spark 二进制文件到目标目录。 - 设置 `SPARK_HOME` 和 `PYTHONPATH` 环境变量以便正确初始化 PySpark。 - 如果需要自动化配置流程,可借助第三方库 `findspark` 来简化设置过程。 ```python import findspark spark_home = "/path/to/your/spark" python_path = "/path/to/your/python" findspark.init(spark_home, python_path) ``` 上述代码片段展示了如何通过 `findspark` 初始化 PySpark 环境[^2]。 --- #### 创建 SparkSession 并加载数据 从 Spark 2.x 开始,推荐使用统一入口 `SparkSession` 替代旧版的 `SQLContext` 或 `HiveContext`。下面是一个简单的例子来创建 SparkSession 实例: ```python from pyspark.sql import SparkSession # 创建 SparkSession 对象 spark = SparkSession.builder \ .appName("example") \ .master("local[*]") \ .getOrCreate() # 加载 CSV 文件作为 DataFrame df = spark.read.csv("/path/to/file.csv", header=True, inferSchema=True) # 显示前几行数据 df.show() ``` 此部分介绍了如何利用 `SparkSession` 进行数据读取与展示。 --- #### 数据转换与动作 (Transformation & Action) PySpark 支持两种主要的操作模式:**转换 (Transformations)** 和 **动作 (Actions)**。前者定义计算逻辑而后者触发实际执行[^3]。 ##### 示例:WordCount 应用程序 这是一个经典的 WordCount 示例,演示了如何统计文本中的单词频率: ```python text_file = sc.textFile("/path/to/input.txt") word_counts = text_file.flatMap(lambda line: line.split()) \ .map(lambda word: (word, 1)) \ .reduceByKey(lambda a, b: a + b) for wc in word_counts.collect(): print(wc) ``` 该脚本实现了如下功能: 1. 将每行字符串拆分为多个单词; 2. 给每个单词分配计数值为 1; 3. 合并相同键对应的值以得到最终的结果集。 --- #### 更多学习资源 对于希望深入理解 PySpark 的开发者来说,GitHub 上有一份详尽的学习资料可供参考[^4]。它不仅覆盖了核心概念还包含了大量实践案例帮助巩固知识点。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值