spark的rdd高级用法 --算子

1.算子介绍

rdd中封装了各种算子方便进行计算,主要分为两类

  • transformation

    • 转化算子 对rdd数据进行转化计算得到新的rdd ,定义了一个线程任务

  • action

    • 执行算子 触发计算任务,让计算任务进行执行,得到结果

    • 触发线程执行的

rdd的转化算子大部分都是从rdd中读取元素数据(rdd中每条数据),具体计算需要开发人员编写函数传递到rdd算子中

rdd的执行算子则大部分是用来获取数据 collect方法就是触发算子。

2.常用算子的应用

2.1map

# 转化算子map的使用
from pyspark import SparkContext

# 创建SparkContext对象
sc = SparkContext()

# 生成rdd
data = [1, 2, 3, 4]
rdd = sc.parallelize(data)


# 对rdd进行计算
# 转化算子map使用
# 将处理数据函数当成参数传递给map
# 定义函数只需要一个接受参数
def func(x):
    """
        数据计算逻辑函数
    :param x: 接收每一个rdd的元素数据
    :return:
    """
    return x + 1


def func2(x):
    """
        数据计算逻辑函数
    :param x: 接收每一个rdd的元素数据
    :return:
    """
    return str(x)


# 转化算子执行后会返回新的rdd
rdd_map = rdd.map(func)
rdd_map2 = rdd.map(func2)
rdd_map3 = rdd_map2.map(lambda x: [x])

# 对rdd数据结果展示
# 使用rdd的触发算子,collect获取是所有的rdd元素数据
res = rdd_map.collect()
print(res)

res2 = rdd_map2.collect()
print(res2)


res3 = rdd_map3.collect()
print(res3)

2.2flatMap

处理的是二维嵌套列表数据

from pyspark import SparkContext

# 创建SparkContext对象
sc = SparkContext()

# 生成rdd
data = [[1, 2], [3, 4]]
data2 = ['a,b,c','d,f,g']  # 将数据转为['a','b','c','d','f','g']
rdd = sc.parallelize(data)
rdd2 = sc.parallelize(data2)

# rdd计算
# flatMap算子使用  将rdd元素中的列表数依次遍历取出对应的值放入新的rdd [1,2,3,4]
# 传递一个函数,函数接受一个参数
rdd_flatMap = rdd.flatMap(lambda x: x)

rdd_map = rdd2.map(lambda x:x.split(','))
rdd_flatMap2 = rdd_map.flatMap(lambda x:x)

# 输出展示数据
# 使用执行算子
res  = rdd_flatMap.collect()
print(res)

res2  = rdd_map.collect()
print(res2)

res3 = rdd_flatMap2.collect()
print(res3)

2.3fliter

条件过滤的书写和Python中if判断一样

rdd7 = sc.parallelize([1, 2, 3, 4])
rdd8 = sc.parallelize(['a', 'b', 'c', 'a'])
# filter算子,可以接受rdd中每个元素数据,然后传递给函数进行过滤
# lambda需要有一个接收值x,x接收到每个元素数据后,如何进行过滤需要写判断逻辑

# 判断条件的书写逻辑和if的判断逻辑一样
filter_rdd = rdd7.filter(lambda x: x > 2)
filter_rdd2 = rdd8.filter(lambda x: x == 'a')

2.4distinc

去重

distinct_rdd = rdd.distinct()

2.5groupBy

分组

# 5、对数据进行分组
# groupBy是分组算子,会读取rdd中每个元素数据,传递给函数使用
# lambda需要一个接收值x,接收groupBy传递的元素数据,然后指定分组规则
# hash(x) % 2  对x中的元素数据进行hash取余,将数据分成两组,余数相同的数据会放在一起
# groupBy返回一个新的rdd,rdd的结构形式是  [(key,value),(k,v)]
groupBy_rdd = rdd8.groupBy(lambda x: hash(x) % 2)

# 6、对kv形式的数据进行取值处理
# mapValues,可以获取kv中的value值部分传递给函数进行使用
# mapValues返回一个新的rdd数据
mapValues_rdd = groupBy_rdd.mapValues(lambda x: list(x))

2.6sortBy() 排序

  • rdd.sortBy(lambda x:x,ascending=False)   倒序

  • rdd.sortBy(lambda x:x)正序

 3.常用action算子

  • collect() 取出rdd中所有值

    • rdd.collect()

  • reduce() 非k-v类型数据累加 [1,2,3,4,6]

    • rdd.reduce(lambda 参数1,参数2:两个参数计算)

  • count() 统计rdd元素个数

    • rdd.count()

  • take() 取出指定数量值

    • rdd.take(数量)


# 执行算子的使用
from pyspark import SparkContext

sc = SparkContext()

# python转为rdd
rdd = sc.parallelize([1, 2, 3, 4, 5, 6])
# 触发计算
# action算子计算完成返回的是计算结果,不在是rdd了,不能在进行rdd操作了
# collect方法,触发计算获取是所有计算结果
res = rdd.collect()
print(res)
# reduce方法,传递一个计算逻辑,对元素数据进行累加计算
# 可以不需要转化算直接累加计算,但是不能处理kv形式数据
res  = rdd.reduce(lambda x,y:x+y)
# x初始为0 y一次获取元素数据   x=0,y=1 x= x+y=1
# x=1,y=2  x+y=3
# x=3,y=3  x+y=6
print(res)

# count 获取rdd元素个数
res = rdd.count()
print(res)

# take取指定数量的元素数据
res=rdd.take(3)
print(res)

3.1关联与合并 

  • union 合并两个rdd 不去重

  • join k-v类型数据 通过key进行关联

# 多个rdd操作
from pyspark import SparkContext

sc = SparkContext()

rdd1 = sc.parallelize([1,2,3,4])
rdd2 = sc.parallelize([5,6,7,4])

rdd_kv1 = sc.parallelize([('a',1),('b',2),('c',3)])
rdd_kv2 = sc.parallelize([('c',4),('d',5),('e',6)])

# rdd之间的合并
union_rdd = rdd1.union(rdd2)
union_kv_rdd = rdd_kv1.union(rdd_kv2)


# kv形式rdd进行join关联  通过key关联
# 内关联  相同key的数据会保留下来
join_rdd = rdd_kv1.join(rdd_kv2)
# 左关联   左边rdd的数据会被保留下来,如果右边rdd有对应的key值数据会显示,没有对应key值会显示为空
leftOuterJoin_rdd = rdd_kv1.leftOuterJoin(rdd_kv2)
# 右关联   右边rdd的数据会被保留下来,如果左边rdd有对应的key值数据会显示,没有对应key值会显示为空
rightOuterJoin_rdd = rdd_kv1.rightOuterJoin(rdd_kv2)

# 查看结果
res = union_rdd.collect()
print(f'union合并结果:{res}')
res2 = union_kv_rdd.collect()
print(f'kv_union合并结果:{res2}')
res3 = join_rdd.collect()
print(f'join内关联结果:{res3}')
res4 = leftOuterJoin_rdd.collect()
print(f'左关联结果:{res4}')
res5 = rightOuterJoin_rdd.collect()
print(f'右关联结果:{res5}')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值