PySpark学习: PySpark数据计算

文章目录

  • PySpark数据计算
    • [map 方法](#map 方法)
    • 链式调用
    • [flatMap 方法](#flatMap 方法)
    • [reduceByKey 算子](#reduceByKey 算子)
    • [filter 方法](#filter 方法)
    • [distinct 方法](#distinct 方法)
    • [sortBy 方法](#sortBy 方法)

PySpark数据计算

PySpark 的数据计算, 都是基于RDD对象来进行的

RDD对象内置丰富的成员方法 (算子)

map 方法

功能: map算子, 是将RDD的数据一条条处理, (处理的逻辑基于map算子中接收的处理函数), 返回新的RDD

语法:

python 复制代码
rdd.map(func)
# func :    f:(T) → U

f: 表示这是一个函数(方法)

(T) → U 表示的是方法的定义:

() 表示传入参数, (T) 表示 传入1个参数 , () 表示没有传入参数

T 是泛型的代称, 在这里表示 任意类型

U 也是泛型代称, 在这里表示 任意类型

→ U 表示返回值

(T) → U 总结起来的意思是: 这是一个方法, 这个方法接受一个参数传入, 传入参数类型不限. 返回一个返回值, 返回值类型不限.

(A) → A 总结起来的意思是: 这是一个方法, 这个方法接受一个参数传入, 传入参数类型不限. 返回一个返回值, 返回值和传入参数类型一致

例如:

通过map() 方法将列表中每一个数字乘以 10

python 复制代码
from pyspark import SparkConf, SparkContext

conf = SparkConf().setMaster("local").setAppName("PySpark_test")

sc = SparkContext(conf = conf)

rdd = sc.parallelize([1, 2, 3, 4, 5])

def func(data):
    return data * 10
# 通过map 方法将全部数据乘以 10
# rdd2 = rdd.map(func)

# 匿名函数
rdd2 = rdd.map(lambda x : x * 10)

print(rdd2.collect()) # [10, 20, 30, 40, 50]

链式调用

对于返回值是新的 RDD 的算子, 可以通过链式调用的方法多次调用算子

例如: 给列表中的数据乘以 10 再加上 5

python 复制代码
from pyspark import SparkConf, SparkContext

conf = SparkConf().setMaster("local").setAppName("PySpark_test")

sc = SparkContext(conf = conf)

rdd = sc.parallelize([1, 2, 3, 4, 5])

# 链式调用
# 给列表中的数据乘以 10 再加上 5
rdd2 = rdd.map(lambda x : x * 10).map(lambda x : x + 5)

print(rdd2.collect()) # [15, 25, 35, 45, 55]

flatMap 方法

功能: 对 rdd 执行 map 操作, 然后进行接触嵌套操作

什么是接触嵌套呢; 请看下面示例:

python 复制代码
# 嵌套的list 
list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

# 解除了嵌套
list = [1, 2, 3, 4, 5, 6, 7, 8, 9]

通过collect() 返回的是以一个 list

python 复制代码
from pyspark import SparkConf, SparkContext

conf = SparkConf().setMaster("local").setAppName("PySpark")

sc = SparkContext(conf = conf)

lst = ["hello world", "hello xinyan", "I am John"]

rdd = sc.parallelize(lst)
print(rdd.collect())

rdd2 = rdd.map(lambda x: x.split(" "))
print(rdd2.collect()) # [['hello', 'world'], ['hello', 'xinyan'], ['I', 'am', 'John']]

rdd3 = rdd.flatMap(lambda x: x.split(" "))
print(rdd3.collect()) # ['hello', 'world', 'hello', 'xinyan', 'I', 'am', 'John']

flatMap算子的计算逻辑和map一样, 只是比 map 多出了一层解除嵌套的逻辑

reduceByKey 算子

功能: 针对KV型 RDD, 自动按照 key 分组, 然后根据提供的聚合逻辑, 完成 组内数据 (value) 的聚合操作

KV 型RDD: 存储的数据是二元元组 (元组中的数据只有两个)

用法;

python 复制代码
rdd.reduceByKey(func) 
# func: (v, v) -> v
# 接受两个参数(类型要求一致), 返回一个返回值, 类型和传入的参数类型要求一致
python 复制代码
from pyspark import SparkConf, SparkContext

conf = SparkConf().setMaster("local").setAppName("PySpark")

sc = SparkContext(conf = conf)

tuple1 = (('a', 1), ('b', 2), ('a', 3), ('b', 4))

rdd = sc.parallelize(tuple1)

rdd2 = rdd.flatMap(lambda x: x) # ['a', 1, 'b', 2, 'a', 3, 'b', 4]
print(rdd2.collect())

result = rdd.reduceByKey(lambda x, y: x + y)
print(result.collect()) # [('a', 4), ('b', 6)]

reduceByKey 中的聚合逻辑:

例如: 有1, 2, 3, 4, 5, 然后聚合函数是: lambda a, b: a + b

filter 方法

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

语法:

python 复制代码
rdd.filter(func) 
# func: (T) -> bool 传入一个任意类型参数, 返回值必须是一个True 或者 False

函数对 RDD 数据逐个处理, 得到 True 的保留至返回值的 RDD 中

返回True 的数据保留, 返回 False 的数据被丢弃

python 复制代码
from pyspark import SparkConf, SparkContext

conf = SparkConf().setMaster("local").setAppName("pySpark_test_App")
sc = SparkContext(conf = conf)

lst = [1, 2, 3, 4, 5]
rdd = sc.parallelize(lst)

rdd2 = rdd.filter(lambda x: x % 2 == 0)

print(rdd2.collect()) # [2, 4]

distinct 方法

功能: 对RDD数据进行去重: 返回新的RDD

语法:

python 复制代码
rdd.distinct() # 无需传参
python 复制代码
from pyspark import SparkConf, SparkContext

conf = SparkConf().setMaster("local").setAppName("pySpark_test_App")
sc = SparkContext(conf = conf)

lst = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 3, 3, 3, 4, 3, 2, 2, 2, 1]
rdd = sc.parallelize(lst)

rdd2 = rdd.distinct()

print(rdd2.collect()) # [1, 2, 3, 4, 5]

distinct 返回的顺序不一定严格[1,2,3,4,5],RDD 是分布式,输出顺序不保证

sortBy 方法

功能: 基于指定的排序依据对RDD数据进行排序

语法:

python 复制代码
rdd.sortBy(func, ascending = False, numPartitions = 1) 
# func: (T) -> U: 告知按照rdd中的哪个数据进行排序, 比如 lambda x: x[1], 表示按照 rdd 中的第二个元素进行排序
# ascending  True升序, False降序
# numPartitions: 用多少区排序
python 复制代码
from pyspark.sql import SparkSession
spark = SparkSession.builder.master("local").appName("SparkName").getOrCreate()
sc = spark.sparkContext

rdd = sc.parallelize((('a', 1), ('b', 3), ('c', 9), ('d', 7), ('e', 5)))
rdd2 = rdd.sortBy(lambda x: x[1], ascending=False, numPartitions=1)
print(rdd2.collect()) # [('c', 9), ('d', 7), ('e', 5), ('b', 3), ('a', 1)]

全局排序需要设置分区数为 1

相关推荐
Java后端的Ai之路1 小时前
01、Python - 设计模式介绍
java·人工智能·python·设计模式·通用
EW Frontier1 小时前
【DOA估计】四根天线、一块SDR,神经网络把测向误差压进2度以内【附python代码】
人工智能·python·神经网络·doa估计·aoa估计
denggun123451 小时前
Python两套原生信号量与swift对比
开发语言·python·swift
starzy19902 小时前
SparkStreaming 之接收数据原理剖析
大数据·spark
qq_161111273 小时前
Jenkins+Python自动化测试持续集成详细教程
自动化测试·python·jenkins·教程·持续集成
爱吃苹果的梨叔6 小时前
训练集群网络中断怎么办?智算机房的 Console 串口排障方案
网络·python·智能路由器·php
李妍.10 小时前
02Numpy基础(上)
开发语言·python
TheBestRucy10 小时前
Python 九阳神功之贰:面向对象(下)
开发语言·python
2601_9659584610 小时前
口腔黏膜脱皮超2周未愈建议及时就医
人工智能·python
吃着火锅x唱着歌11 小时前
Effective C++ 学习笔记 条款43 学习处理模板化基类内的名称
c++·笔记·学习