#pyspark shell
rdd = sc.parallelize(["hello world","hello spark"]);
rdd2 = rdd.flatMap(lambda line:line.split(" "));
rdd3 = rdd2.map(lambda word:(word,1));
rdd5 = rdd3.reduceByKey(lambda a, b : a + b);
rdd5.collect();
quit();
# vscode
#pip install findspark
#fix:ModuleNotFoundError: No module named 'pyspark'
import findspark
findspark.init()
#############################
from pyspark import SparkConf, SparkContext
# 创建SparkContext
conf = SparkConf().setAppName("WordCount").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize(["hello world","hello spark"]);
rdd2 = rdd.flatMap(lambda line:line.split(" "));
rdd3 = rdd2.map(lambda word:(word,1));
rdd5 = rdd3.reduceByKey(lambda a, b : a + b);
#print,否则无法显示结果
#[('spark', 1), ('hello', 2), ('world', 1)]
print(rdd5.collect());
#防止多次创建SparkContexts
sc.stop()
#jupyter
from pyspark.sql import SparkSession
spark = SparkSession.builder.master("local[*]").appName("WordCount").getOrCreate();
sc = spark.sparkContext
rdd = sc.parallelize(["hello world","hello spark"]);
rdd2 = rdd.flatMap(lambda line:line.split(" "));
rdd3 = rdd2.map(lambda word:(word,1));
rdd5 = rdd3.reduceByKey(lambda a, b : a + b);
#print,否则无法显示结果
#[('spark', 1), ('hello', 2), ('world', 1)]
print(rdd5.collect());
#防止多次创建SparkContexts
sc.stop()
collect 把RDD类型数据转化为数组 同时从集群中拉取数据dirver端
stats 返回RDD元素的计数、均值、方差、最大值和最小值
countByKey 统计RDD[K,V]中每个K的数量 每个相同的K 结果加一 不是把V的值相加
first: 返回RDD中一个元素
max: 返回最大的一个元素
sum: 返回和
take: 返回前n个元素
top: 返回排序后的前n个元素 降序 top(10,key=str):按照字典序排序 前10个
count: 返回个数
collect :把RDD类型数据转化为数组 同时从集群中拉取数据dirver端
collectAsMap: 把键值RDD转换成Map映射保留其键值结构
countByKey: 统计RDD[K,V]中每个K的数量 每个相同的K 结果加一 不是把V的值相加
countByValue :统计一个RDD中各个Value出现的次数,返回字典,key是元素的值,value是出现的次数/
sc.parallelize(range(2,100)) 等价于 sc.range(2,100)
rdd3 = sc.parallelize([("a",1),("a",1),("b",2),("a",1)])
print(rdd3.countByKey())
#defaultdict(, {'a': 3, 'b': 1})
print(rdd3.countByValue())
#defaultdict(, {('a', 1): 3, ('b', 2): 1})
stats:返回RDD元素的计数、均值、方差、最大值和最小值
rdd = sc.parallelize(range(100))
print(rdd.stats())
#(count: 100, mean: 49.5, stdev: 28.86607004772212, max: 99, min: 0)
aggregate : aggregate(zeroValue,seqOp,combOp) 使用seqOP函数和给定的zeroValue聚合每个分区上的元素,然后用CombOp和zeroValue聚合所有分区结果
data=[1,3,5,7,9,11,13,15,17]
rdd=sc.parallelize(data,2)
print(rdd.glom().collect())
# [[1, 3, 5, 7], [9, 11, 13, 15, 17]]
seqOp = (lambda x, y: (x[0] + y, x[1] + 1)) #求和 和 个数
combOp = (lambda x, y: (x[0] + y[0], x[1] + y[1]))
a=rdd.aggregate((0,0),seqOp,combOp)
#(81, 9)=(0,0)+(16,4)+(65,5)
coalesce 重新分区
filter 过滤
map 每个元素转换
flatmap 每个元素转换并扁平化
mapPartitions 按分区转换
mapValues KV格式 保留k 对v操作
reduce 减少个数 ; reducebykey KV格式 对v操作 减少元素个数
join 内链接; fullOuterJoin 全外部连接
groupBy 函数的返回作为k 分组 ;groupByKey KV中的K分组
keys 、values获取 对应序列
zip 元素相同 一一对应
union 合并; substract 减法 ; intersection 交集; certesian交集
cache、persist 缓存
glom 查看分区状态
sortBy:对RDD元素进行排序
coalesce:rdd.coalesce(numPartitions,[isShuffle=False]) 将RDD进行重新分区,分区过程中是否进行混洗操作
rdd=sc.parallelize([1, 2, 3, 4, 5], 3).glom()
#[[1], [2, 3], [4, 5]]
rdd2 = sc.parallelize([1, 2, 3, 4, 5, 6], 3).coalesce(1,False)
#[1, 2, 3, 4, 5, 6]
repartition: 和coalesce(1,True) 一样 重新分区并混洗
distinct :去重
filter:返回满足过滤函数为True的元素构成 filter(lambda x: x%2 == 0)
#filter
rdd5 = sc.parallelize([1,2,3,4,5]).filter(lambda x: x%2 == 0)
print(rdd5.collect())
[2,4]
map:对RDD每个元素按照func定义的逻辑处理,在统计单词个数中常用rdd.map(func,preservesPartitioning=Flase)
rdd = sc.parallelize(["b", "a", "c", "d"])
rdd2 = rdd.map(lambda x: (x, 1))
#[('b', 1), ('a', 1), ('c', 1), ('d', 1)]
flatMap:对RDD中每一个元素按照func的处理逻辑操作,并将结果扁平化处理
#faltMap
rdd5 = sc.parallelize([1,2,3,4,5]).flatMap(lambda x:[(x,1)])
print(rdd5.collect())
[(1, 2), (2, 4), (3, 6), (4, 8), (5, 10)]
flatMapValues:对RDD元素格式为KV对中的Value进行func定义的逻辑处理,形成新的KV,并把结果扁平化处理
#flatMapValues
rdd = sc.parallelize([("a", [1, 2, 3]), ("c", ["w", "m"])])
ret = rdd.flatMapValues(lambda x: x)
#[('a', 1), ('a', 2), ('a', 3), ('c', 'w'), ('c', 'm')]
mapPartitions:RDD每个分区中元素按照定义的逻辑返回处理,并分别返回值
rdd = sc.parallelize([1, 2, 3, 4 , 5], 2)
def f(iter):
yield sum(iter) #yield的作用是把函数变成generator,返回的是iterable对象
rdd2 = rdd.mapPartitions(f)
print(rdd2.collect())
#[3,12]
mapValues:对KV格式的RDD中的每个元素应用函数,K值不变且保留原始分区, 对Value操作
rdd = sc.parallelize([("a", ["hello", "spark", "!"]), ("b", ["cumt"])])
rdd2 = rdd.mapValues(lambda x:len(x))
#[('a', 3), ('b', 1)]
mapPartitionsWithIndex:RDD每个分区中元素按照定义的逻辑返回处理,跟踪原始分区的索引
rdd = sc.parallelize([1, 2, 3, 4 ,5 ,6], 3)
def f(index, iter):
#分区索引 0,1,2
print(index)
for x in iter:
#1,2;3,4;5,6
print(x)
yield index
ret = rdd.mapPartitionsWithIndex(f).sum()
#3=0+1+2
print(ret)
reduce : 按照func对RDD元素计算,减少元素个数
rdd = sc.parallelize([1, 2, 3, 4, 5])
ret = rdd.reduce(lambda x,y : x+y)
15
reduceByKey : 对KV的数据进行运算,减少元素个数
rdd = sc.parallelize([("a", 1), ("b", 1), ("a", 2),("b", 3)])
rdd2 = rdd.reduceByKey(lambda x,y:x+y)
#[('a', 3), ('b', 4)]
join: 包含自身和另一个匹配键的所有成对元素,每对元素以(k,(v1,v2))元组返回,其中(k,v1)在自身,(k,v2)在另一个中
x = sc.parallelize([("a", 1), ("b", 4)])
y = sc.parallelize([("a", 2), ("a", 3)])
ret = x.join(y).collect()
#[('a', (1, 2)), ('a', (1, 3))]
fullOuterJoin : 全外部连接 没有匹配到就是None
x = sc.parallelize([("a", 1), ("b", 4)])
y = sc.parallelize([("a", 2), ("c", 8)])
rdd = x.fullOuterJoin(y)
# [('a', (1, 2)), ('b', (4, None)), ('c', (None, 8))]
leftOuterJoin 和 rightOuterJoin : 左外连接 和 右外连接
x = sc.parallelize([("a", 1), ("b", 4)])
y = sc.parallelize([("a", 2), ("c", 8)])
rdd = x.leftOuterJoin(y)
#[('b', (4, None)), ('a', (1, 2))]
rdd = x.rightOuterJoin(y)
#[('c', (None, 8)), ('a', (1, 2))]
groupBy :groupBy(func,numPartitions=None,partitionFunc=
rdd = sc.parallelize([1, 2, 3, 4, 5, 10])
rdd = rdd.groupBy(lambda x:x%2)
result = rdd.collect()
#[(0, ), (1, )]
ret = sorted([(x, sorted(y)) for (x, y) in result])
#[(0, [2, 4, 10]), (1, [1, 3, 5])]
groupByKey : 将RDD中每个键的值分组为单个序列,用numsPartitions分区对生成的RDD进行哈希分区 如果求和或平均值 建议使用reduceByKey 或 AggregateByKey
rdd = sc.parallelize([("a", 1), ("b", 1), ("a", 1)])
rdd2 = rdd.groupByKey().mapValues(lambda x: sum(x))
rdd3 = rdd.reduceByKey(lambda x,y: x+y) #和rdd2一样
# [('a', 2), ('b', 1)]
print(sorted(rdd2.collect()))
keyBy: 将原有RDD中的元素作为Key,Key通过func返回值作为value创建一个元组
rdd = sc.parallelize(range(0,3))
rdd = rdd.keyBy(lambda x: x*x)
#[(0, 0), (1, 1), (4, 2)]
keys:获取KV格式中的Key序列,返回新的RDD
rdd1 = sc.parallelize([("a",1),("b",2),("a",3)])
print(rdd1.keys().collect())
#['a', 'b', 'a']
values:获取KV格式中的Value序列,返回新的RDD
rdd1 = sc.parallelize([("a",1),("b",2),("a",3)])
print(rdd1.keys().collect())
#[1, 2, 3]
zip:rdd.zip(otherRDD)将第一个RDD中的元素作为Key,第二个RDD中的作为Value组成新的RDD,两个RDD的元素个数相同
x = sc.parallelize(range(1,6))
y = sc.parallelize(range(801, 806))
print(x.zip(y).collect())
#[(1, 801), (2, 802), (3, 803), (4, 804), (5, 805)]
#x,y长度必须相等
zipWithIndex:RDD元素作为key,索引作为Value
rdd = sc.parallelize(["a", "b", "c", "d"], 3)
print(rdd.zipWithIndex().collect())
#[('a', 0), ('b', 1), ('c', 2), ('d', 3)]
union:第一个RDD元素和第二个的合并
dd =sc.parallelize(range(1,10))
rdd2 =sc.parallelize(range(11,20))
rdd3 = rdd.union(rdd2)
#[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19]
subtract:第一个中排出第二个中的元素
x = sc.parallelize([("a", 1), ("b", 4), ("b", 5), ("a", 3)])
y = sc.parallelize([("a", 1), ("b", 5)])
z = x.subtract(y)
#[('b', 4), ('a', 3)]
subtractByKey :从元素为KV格式的RDD中除掉另一个,只要Key一样就删除
x = sc.parallelize([("a", 1), ("b", 4), ("c", 5), ("a", 3)])
y = sc.parallelize([("a", 7), ("b", 0)])
z = x.subtractByKey(y)
#[('c', 5)]
intersection:返回交集并去重
rdd1 = sc.parallelize([("a", 2), ("b", 1), ("a", 2),("b", 3)])
rdd2 = sc.parallelize([("a", 2), ("b", 1), ("e", 5)])
ret = rdd1.intersection(rdd2).collect()
#('a', 2), ('b', 1)]
certesian: 返回两个RDD的笛卡尔积 元素较多可能出现内存不足情况
rdd = sc.parallelize([1, 2])
rdd2 = sc.parallelize([3, 7])
rdd3 = sorted(rdd.cartesian(rdd2).collect())
#[(1, 3), (1, 7), (2, 3), (2, 7)]
print(rdd3)
sortBy:对RDD元素进行排序,sortBy(keyfuc,ascending=True,numPartitions=None),默认升序
rdd = [('a', 6), ('f', 11), ('c', 7), ('d', 4), ('e', 5)]
rdd2 = sc.parallelize(rdd).sortBy(lambda x: x[0])
#[('a', 6), ('c', 7), ('d', 4), ('e', 5), ('f', 2)]
rdd3 = sc.parallelize(rdd).sortBy(lambda x: x[1])
#[('f', 2), ('d', 4), ('e', 5), ('a', 6), ('c', 7)]
rdd3 = sc.parallelize(rdd).sortBy(lambda x: x[1],False)
#[('c', 7), ('a', 6), ('e', 5), ('d', 4), ('f', 2)]
sortByKey : 按照Key排序 sortByKey(ascending=True,numPartitions=None,keyfunc=)
x = [('a', 6), ('f', 2), ('c', 7), ('d', 4), ('e', 5)]
rdd = sc.parallelize(x).sortByKey(True, 1)
#[('a', 6), ('c', 7), ('d', 4), ('e', 5), ('f', 2)]
print(rdd.collect())
takeOrdered:RDD中获取排序后的前num个元素构成RDD,默认升序,可支持可选函数
rdd =sc.parallelize(range(2,100))
print(rdd.takeOrdered(10))
#[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
print(rdd.takeOrdered(10, key=lambda x: -x))
#[99, 98, 97, 96, 95, 94, 93, 92, 91, 90]
takeSample:takeSample(withReplacement,num,seed=None) 抽样出固定大小的子数据集合,第一个参数布尔值表示是否可以多次抽样,第二个抽样的个数,第三个随机数生成器种子
dd =sc.parallelize(range(2,10))
print(rdd.takeSample(True, 20, 1))
#True代表一个元素可以出现多次
#[5, 9, 5, 3, 2, 2, 7, 7, 5, 7, 9, 9, 5, 3, 2, 4, 5, 5, 6, 8]
print(rdd.takeSample(False, 20, 1))
#False代表一个元素只能出现1次
#[5, 8, 3, 7, 9, 2, 6, 4]
sample : sample(withReplacement,fraction,seed) 第二个参数 抽样比例[0,1]
rdd = sc.parallelize(range(100), 1)
ret = rdd.sample(False, 2, 1)
#可能输出[9, 11, 13, 39, 49, 55, 61, 65, 90, 91, 93, 94]
randomSplit:按照权重对RDD随机切分,返回多个RDD构成的列表
rdd = sc.parallelize(range(100), 1)
rdd1, rdd2 = rdd.randomSplit([2, 3], 10)
print(len(rdd1.collect())) #40
print(len(rdd2.collect())) #60
loopup: 根据key值从RDD中找到相关的元素,返回KV中的V
rdd = sc.parallelize([('a', 'b'), ('c', 'd')])
print(rdd.lookup('a')) #['b']
fold:对RDD每个元素按照func的逻辑进行处理fold(value,func) func有两个参数a,b a的初始值为value,后续为累加值,b代表当前元素值 可以用来累加 累乘
#fold
ret=sc.parallelize([1, 2, 3, 4, 5]).fold(0, lambda x,y:x+y)
#15
ret=sc.parallelize([1, 2, 3, 4, 5]).fold(1, lambda x,y:x*y)
#120
foldByKey:对RDD元素格式为KV对中的Key进行func定义的逻辑处理,可以用来分组累加累乘
#foldByKey
rdd = sc.parallelize([("a", 1), ("b", 2), ("a", 3),("b", 5)])
rdd2=rdd.foldByKey(0, lambda x,y:x+y)
# [('a', 4), ('b', 7)]
rdd3=rdd.foldByKey(1, lambda x,y:x*y)
# [('a', 3), ('b', 10)]
foreach:对RDD每个元素按照func定义的逻辑处理
foreachPartion:对RDD每个分区中的元素按照func定义逻辑处理,一般来说foreachPartion效率比foreach高,是一次性处理一个partition数据,在写数据库的时候,性能比map高很多
rdd = sc.parallelize([("a", 1), ("b", 2), ("a", 3),("b", 5)])
def f(x):
print(x)
return (x[0],x[1]*2)
def f2(iter):
for x in iter:
print(x)
ret = rdd.foreach(f)
ret2 = sc.parallelize([1,2,3,4,5,6,7,8],2).foreachPartition(f2)
aggregateByKey:aggregate(zeroValue,seqFunc,combFunc,numPartitions=None,partitionFunc=) 使用seqFunc函数和给定的zeroValue聚合每个分区上的元素,然后用CombFunc和zeroValue聚合所有分区结果
data=[("a",1),("b",2),("a",3),("b",4),("a",5),("b",6),("a",7),("b",8),("a",9),("b",10)]
rdd=sc.parallelize(data,2)
print(rdd.glom().collect())
#[[('a', 1), ('b', 2), ('a', 3), ('b', 4), ('a', 5)], [('b', 6), ('a', 7), ('b', 8), ('a', 9), ('b', 10)]]
def seqFunc(x,y):
return x + y
def combFunc(x,y):
return x + y
a=rdd.aggregateByKey(0,seqFunc,combFunc)
# [('b', 30), ('a', 25)]
print(a.collect())
combineByKey:
a = [1,2]
b = [10,11]
a.extend(b) #[1, 2, 10, 11]
a.append(b) #[1, 2, [10, 11]]
#combineByKey
rdd = sc.parallelize([("a", 1), ("b", 3), ("a", 2),("b", 4)],2)
def to_list(a):
return [a]
def append(a, b): #分区合并
a.append(b)
return a
def extend(a, b):#不同分区合并
a.extend(b)
return a
print(rdd.glom().collect())
ret = sorted(rdd.combineByKey(to_list, append, extend).collect())
#[[('a', 1), ('b', 3)], [('a', 2), ('b', 4)]]
#[('a', [1, 2]), ('b', [3, 4])]
glom:把RDD中每一个分区的元素T转换成Array[T],每个分区只有一个数组元素
#glom
rdd2 = sc.parallelize([1,2,3,4,5],3)
print(rdd2.collect())
#[1, 2, 3, 4, 5]
print(rdd2.glom().collect())
#[[1], [2, 3], [4, 5]]
print(rdd2.coalesce(1).glom().collect())
#[[1, 2, 3, 4, 5]]
cache : 缓存 默认存储级别(MEMORY_ONLY)
persist : 缓存 可以定制存储级别 storageLevel
saveAsTextFile: 保存RDD文件作为一个对象,