Spark-RDD

本文主要介绍Spark中RDD的操作,包括创建操作对象的方式。详细阐述了RDD的转换操作,如filter、map等,这些操作仅进行逻辑转换。还说明了行动操作会真正执行计算,以及持久化操作能保存常用值,降低读写开销,如persist()、cache()等方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spark中关于RDD的操作

创建操作对象:

from pyspark import SparkContext,SparkConf
from pyspark.sql import SparkSession,Row
import json
conf = SparkConf().setAppName("test1").setMaster("local")
sc = SparkContext(conf=conf)

加载数据

  1. 自定义数据
rdd = sc.parallelize("sd:f:sdf:sdf")
rdd1 = rdd.map(lambda x:x.split(":")).filter(lambda x:len(x[0])>0).map(lambda x:(x[0],1))
rdd2 = rdd1.reduceByKey(lambda a,b:a+b)
print(rdd2.collect())	# [('s', 3), ('d', 3), ('f', 3)]
  1. 加载本地文件
rdd1 = sc.textFile("file:///本地文件")	# 导入本地文件
rdd2.1 = sc.textFile("hdfs://localhost:9000/xxxxxxxx")	# 导入HDFS文件
rdd2.2 = sc.textFile("/xxxxxxxx")	# 导入HDFS文件
rdd2.3 = sc.textFile("xxxx.txt")	# 导入HDFS文件

RDD操作

转换操作

转换操作是对RDD的类型进行逻辑上的转换而已,并没有实际进行运算;
实际的运算要用行动操作

操作含义
filter(func)筛选出满足函数func的元素,并返回一个新的数据集
map(func)将每个元素传递到函数func中,并将结果返回一个新的数据集
flatMap(func)与map相似,但每个输入元素都可以映射到0或者多个输出结果
groupByKey()应用于(K,V)键值对的数据集,返回一个新的(K,Iterable)形式的数据集
reduceByKey(func)应用于(K,V)键值对的数据集,返回一个新的(K,V)形式的数据集,其中每个值是将每个Key传递到函数func中进行聚合操作的结果;func是对值进行处理的!reduceByKey相当于是先做了groupByKey,再对值进行处理
union(rdd)对一个RDD和参数RDD进行并集计算,然后返回新的RDD
intersection(rdd)对RDD和另一个RDD进行交集计算,然后返回新的RDD
sortBy(func)通过func来对RDD内部元素进行排序,默认为升序,False为降序
distinct()去重,返回新的RDD
#!/usr/bin/python
from pyspark import SparkContext
sc = SparkContext("local", "testSparkApi")
rdd = sc.textFile("file:///home/hadoop/sparktest.txt")
'''
Hadoop is good
Spark is fast
Spark is better
'''
filter
filtered = rdd.filter(lambda x:"Spark" in x)
result = filtered.collect()
print("RDD filterApi:%s"%result)
"RDD filterApi:['Spark is fast', 'Spark is better']"
map
maped = rdd.map(lambda x:"hahahaha"+x)	# 在每个元素前面加上hahahaha
result = maped.collect()
print("RDD mapApi:%s"%result)
"RDD mapApi:['hahahahaHadoop is good', 'hahahahaSpark is fast', 'hahahahaSpark is better']"
flatMap

将每个元素进行split操作(map),得到的内容再提取出来,形成一个新的元素(flat)

fm = rdd.flatMap(lambda x:x.split())
result = fm.collect()
print("RDD flatMapApi:%s"%result)
"RDD flatMapApi:['Hadoop', 'is', 'good', 'Spark', 'is', 'fast', 'Spark', 'is', 'better']"
groupByKey

将相同键的值封装成Iterable数据类型

fm = rdd.flatMap(lambda x: x.split())
mapped = fm.map(lambda x:(x,1))
# 将每个元素变成(K,1)的形式
print(mapped.foreach(print))
'''
('Hadoop', 1)
('is', 1)
('good', 1)
('Spark', 1)
('is', 1)
('fast', 1)
('Spark', 1)
('is', 1)
('better', 1)
'''
gbk = mapped.groupByKey()
result = gbk.collect()
print("RDD groupByKeyApi:%s"%result)
'''RDD groupByKeyApi:[('Hadoop', <pyspark.resultiterable.ResultIterable object at 0x7f6ad27d63c8>), 
('is', <pyspark.resultiterable.ResultIterable object at 0x7f6ad27d62b0>), 
('good', <pyspark.resultiterable.ResultIterable object at 0x7f6ad27d6518>), 
('Spark', <pyspark.resultiterable.ResultIterable object at 0x7f6ad27d6438>), 
('fast', <pyspark.resultiterable.ResultIterable object at 0x7f6ad27d65f8>), 
('better', <pyspark.resultiterable.ResultIterable object at 0x7f6ad3419c50>)]
‘’‘


# ------------------------------------
from pyspark import SparkContext,SparkConf
conf = SparkConf().setMaster("local").setAppName("case")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([("a",1),("b",1),("c",1),("a",2),("b",2),("c",2),("a",3),("d",4),("b",5)])
result = rdd.groupByKey().mapValues(list).collect()
print(result)	# [('a', [1, 2, 3]), ('b', [1, 2, 5]), ('c', [1, 2]), ('d', [4])]

reduceByKey

将所有元素相同键的值进行聚合操作,func是对值进行操作的,结果返回新的(K,V)值是聚合操作后的结果

fm = rdd.flatMap(lambda x: x.split())
mapped = fm.map(lambda x:(x,1))
rbk = mapped.reduceByKey(lambda a,b:a+b)
result = rbk.collect()
print("RDD reduceByKeyApi:%s"%result)
'''
RDD reduceByKeyApi:[('Hadoop', 1), ('is', 3), ('good', 1), ('Spark', 2), ('fast', 1), ('better', 1)]
'''
union
from pyspark import SparkContext,SparkConf
conf = SparkConf().setMaster("local").setAppName("case")
sc = SparkContext(conf=conf)
rdd1 = sc.parallelize([1,2,3,4,5])
rdd2 = sc.parallelize([5,6,7,8,1])
tr = rdd1.union(rdd2)
result = tr.collect()
print(result)	# [1, 2, 3, 4, 5, 5, 6, 7, 8, 1]
intersection
from pyspark import SparkContext,SparkConf
conf = SparkConf().setMaster("local").setAppName("case")
sc = SparkContext(conf=conf)
rdd1 = sc.parallelize([1,2,3,4,5])
rdd2 = sc.parallelize([5,6,7,8,1])
tr = rdd1.intersection(rdd2)
result = tr.collect()
print(result)	# [1, 5]
mapValues(f)

在不改变原有Key的基础上,对Key-value结构的RDD的Value值进行一个map操作

from pyspark import SparkContext,SparkConf
conf = SparkConf().setMaster("local").setAppName("case")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([("a",["apple","banana","lemon"]),("b",["grapes"])])
result = rdd.mapValues(lambda x:len(x)).collect()
print(result)	# [('a', 3), ('b', 1)]
flatMapValues(f)

对Key-value结构的RDD先执行mapValue操作(对值进行操作),在执行扁平化操作

from pyspark import SparkContext,SparkConf
conf = SparkConf().setMaster("local").setAppName("case")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([("a",["apple","banana","lemon"]),("b",["grapes"])])
result = rdd.flatMapValues(lambda x:x).collect()
print(result)   # [('a', 'apple'), ('a', 'banana'), ('a', 'lemon'), ('b', 'grapes')]
sortByKey

根据键来排序

from pyspark import SparkContext,SparkConf
conf = SparkConf().setMaster("local").setAppName("case")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([("a",1),("b",1),("c",1),("a",2),("b",2),("c",2),("a",3),("d",4),("b",5),("3",2),("1",4)])
result = rdd.groupByKey().mapValues(list).sortByKey().collect()
print(result)
# [('1', [4]), ('3', [2]), ('a', [1, 2, 3]), ('b', [1, 2, 5]), ('c', [1, 2]), ('d', [4])]
Keys(),Values()

返回RDD内部的键,值

join(rdd)
from pyspark import SparkContext,SparkConf
conf = SparkConf().setMaster("local").setAppName("case")
sc = SparkContext(conf=conf)
x=sc.parallelize([("a",1),("b",2),("c",3)])
y=sc.parallelize([("a",7),("a",8),("a",0)])
result = y.join(x).collect()
print(result)
# [('a', (7, 1)), ('a', (8, 1)), ('a', (0, 1))]

result2 = x.join(y).collect()
print(result2)
# [('a', (1, 7)), ('a', (1, 8)), ('a', (1, 0))]
leftOuterJoin(rdd), rightOuterJoin(rdd)

行动操作

对RDD之前的所有转换进行计算,真正执行!

操作描述
count()返回数据集中的元素个数
collect()以数组的形式返回数据集中的所有元素
fitst()返回数据集中的第一个元素
take(n)以数组的形式返回数据集中的前n个元素
reduce(func)通过函数func(输入两个参数并返回一个值)聚合数据集中的元素[数值求和]
foreach(func)将数据集中的每个元素传递到函数func中运行
top(n)返回RDD内部元素的前n个最大值
saveAsTextFile()将RDD中的元素以字符串的格式存储在文件系统中
collectAsTextFile()将Key-Value结构的RDD以字典的形式返回
countByKey()对每个Key键的元素进行统计
持久化

有时候需要多次访问一些值,但是每次访问这些值都需要再进行计算,这就很消耗时间;持久化可以把你经常访问的值保存起来;
持久化后的RDD将会被保留在计算节点的内存中,被后面的行动操作重复使用

list = ["hadoop", "spark", "hive"]
rdd = sc.parallelize(list)

print(rdd.count()) #行动操作,触发一次真正的从头到尾的计算
print(",".join(rdd.collect()))#行动操作,再触发一次真正的从头到尾的计算
持久化操作

持久化操作能降低读写开销
persist()对一个RDD标记为持久化,但是不是立即持久化的,要通过行动操作,计算出来之后才能被持久化
.persist(MEMORY_ONLY)方法:只存储再内存中
.persist(MEMORY_AND_DISK)内存不足就存放再磁盘中
.cache()方法:会调用persist(MEMORY_ONLY)
手动把持久化的RDD从缓存中移除:.unpersist()

list = ["hadoop", "spark", "hive"]
rdd = sc.parallelize(list)
rdd.cache() # 会调用persist(MEMORY_ONLY),但是,语句执行到这里,并不会缓存rdd,因为这时rdd还没有被计算生成
print(rdd.count()) # 第一次行动操作,触发一次真正的从头到尾的计算,这时上面的rdd.cache()才会被执行,把这个rdd放到缓存中
print(",".join(rdd.collect())) # 第二次行动操作,不需要出发从头到尾的计算,只需要重复使用上面缓存的rdd
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值