Exemple #1
0
# @Author  : adair_chan
# @Email   : [email protected]
# @Date    : 2019/1/22 下午4:55
# @IDE     : PyCharm

from _operator import add
from Init_SparkContext import MySparkContext

sc = MySparkContext().open()

fruits = sc.parallelize([("a", ["apple", "banana", "lemon"]),
                         ("b", ["grapes"]), ("a", ["apple2", "banana2"])])
"""
mapValues():对键值对RDD中的每个value都应用一个函数,但是,key不会发生变化
reduceByKey():对具有相同key的键值对进行合并
"""
t = fruits.mapValues(lambda x: len(x))
t2 = t.reduceByKey(add)
print("\n{0}\n{1}".format(t.collect(), t2.collect()))
# print("\n{0}\n{1}".format(t.collect(), type(t2)))
t3 = fruits.mapValues(lambda x: (x, 1)).reduceByKey(lambda x, y:
                                                    (x[0] + y[0], x[1] + y[1]))
print(t3.collect())
"""
combineByKey() 是最为常用的基于键进行聚合的函数。大多数基于键聚合的函数都是用它 实现的
如果这是一个新的元素,combineByKey()会使用一个叫作 createCombiner() 的函数来创建那个键对应的累加器的初始值。
    -- 需要注意的是,这一过程会在每个分区中第一次出现各个键时发生,而不是在整个 RDD 中第一次出现一个键时发生。
如果这是一个在处理当前分区之前已经遇到的键,它会使用 mergeValue() 方法将该键的累 加器对应的当前值与这个新的值进行合并。
由于每个分区都是独立处理的,因此对于同一个键可以有多个累加器。
如果有两个或者更 多的分区都有对应同一个键的累加器,就需要使用用户提供的 mergeCombiners() 方法将各 个分区的结果进行合并。
"""
Exemple #2
0
# @Author  : adair_chan
# @Email   : [email protected]
# @Date    : 2019/2/19 上午11:09
# @IDE     : PyCharm
"""
利用分区优化charpter1行动操作.py的平均值计算过程
每个分区只创建一次二元组,而不用为每个元素都执行这个操作
"""

from _operator import add

from Init_SparkContext import MySparkContext

sc = MySparkContext().open()
rdd = sc.parallelize([121, 28, 63, 214, 88])


def partitionCtr(nums):
    """计算分区的sumCounter"""
    sumCount = [0, 0]
    for num in nums:
        sumCount[0] += num
        sumCount[1] += 1
    return [sumCount]


def fastAvg(nums):
    """计算平均值"""
    sumCount = nums.mapPartitions(partitionCtr).reduce(add)
    print("计算所得总和为:%f,平均值为:%f" %
          (sumCount[0], sumCount[0] / float(sumCount[1])))
Exemple #3
0
# @Author  : adair_chan
# @Email   : [email protected]
# @Date    : 2019/1/19 下午6:07
# @IDE     : PyCharm
"""
两个最常用的转化操作是 map() 和 filter()
    - map: 接收一个函数,把这个函数用于 RDD 中的每个元素,将函数的返回结果作为结果RDD中对应元素的值
    - filter: 接收一个函数,并将 RDD 中满足该函数的 元素放入新的 RDD 中返回
"""
from Init_SparkContext import MySparkContext

sc = MySparkContext().open()

# 利用map计算平方
nums = sc.parallelize([1, 2, 3, 4])
squared = nums.map(lambda x: x * x).collect()
for num in squared:
    print("%i" % num)
"""
提供给 flatMap() 的函数被分别应用到了输入 RDD 的每个元素上。不 过返回的不是一个元素,而是一个返回值序列的迭代器。
输出的 RDD 倒不是由迭代器组 成的。我们得到的是一个包含各个迭代器可访问的所有元素的 RDD
"""
# 利用flatMap()将行数据切分为单词
lines = sc.parallelize(["hello world", "hi"])
words = lines.flatMap(lambda line: line.split(""))
print(words.first())
# @Author  : adair_chan
# @Email   : [email protected]
# @Date    : 2019/1/19 下午4:24
# @IDE     : PyCharm

from Init_SparkContext import MySparkContext

# 向spark传递函数
log_path = '../../test.log'
rdd = MySparkContext().read_data(log_path)


def contains_error(s):
    return "error" in s


word = rdd.filter(contains_error)


# 传递一个带字段引用的函数
class SearchFunctions(object):
    def __init__(self, query):
        self.query = query

    def is_match(self, s):
        return self.query in s

    # 以下两种方法不推荐
    def get_matches_function_reference(self, rdd):
        # 问题:在"self.isMatch"中引用了整个self
        return rdd.filter(self.is_match)
Exemple #5
0
# @Author  : adair_chan
# @Email   : [email protected]
# @Date    : 2019/1/22 上午9:55
# @IDE     : PyCharm

from Init_SparkContext import MySparkContext

sc = MySparkContext().open()

lines = sc.parallelize(
    ["sacajawea", "recedes", "hello", "haft vaderA Sabbath", "www"])

# 使用第一个单词作为键(这里是以空格划分单词)创建出一个 pair RDD
pairs = lines.map(lambda x: (x.split(" ")[0], x))
# 根据字符长度进行筛选
result = pairs.filter(lambda KeyValue: len(KeyValue[1]) > 7)
print(result.collect())
"""
map和flatMap的区别:
map():对每一条输入进行指定的操作,然后为每一条输入返回一个对象
flatMap(): 操作1:同map函数一样:对每一条输入进行指定的操作,然后为每一条输入返回一个对象
           操作2:最后将所有对象合并为一个对象
"""
rdd = sc.parallelize([2, 3, 4])
print(rdd.map(lambda x: list(range(1, x))).collect())
print(rdd.flatMap(lambda x: range(1, x)).collect())
Exemple #6
0
# @Author  : adair_chan
# @Email   : [email protected]
# @Date    : 2019/1/25 下午2:28
# @IDE     : PyCharm
import json

from Init_SparkContext import MySparkContext

sc = MySparkContext().open()

# 读取文本文件
text = sc.textFile('../test.log')
info = text.filter(lambda s: "error" in s)
info.saveAsTextFile('test')

# 读取json数据
data = sc.textFile('test.json')
data = data.map(lambda x: json.loads(x))
data.foreach(lambda x: print(x))
Exemple #7
0
# @Author  : adair_chan
# @Email   : [email protected]
# @Date    : 2019/1/17 下午5:46
# @IDE     : PyCharm

from Init_SparkContext import MySparkContext

# 读取数据(因为spark的惰性求值,此时并没有真正读取进来数据)
log_path = '../../test.log'
rdd = MySparkContext().read_data(log_path)

# 用filter进行转化操作
errorsRDD = rdd.filter(lambda s: "error" in s and "INFO" not in s)
warningsRDD = rdd.filter(lambda s: "WARN" in s)

# 进行union转化操作
badLinesRDD = errorsRDD.union(warningsRDD)

# 行动操作对错误进行计数
print("Input concerning lines:%d" % badLinesRDD.count())
print("\nHere are 10 examples:")
for line in badLinesRDD.take(10):
    print(line)
"""
RDD 还有一个 collect() 函数,可以用来获取整个RDD 中的数据
但是只有当你的整个数据集能在单台机器的内存中放得下时,才能使用collect()

每当我们调用一个新的行动操作时,整个RDD都会从头开始计算。要避免这种低效的行为,用户可以将中间结果持久化
"""
Exemple #8
0
# @Author  : adair_chan
# @Email   : [email protected]
# @Date    : 2019/2/13 下午7:25
# @IDE     : PyCharm
"""
注意,工作节点上的任务不能访问累加器的值。从这些任务的角度来看,累加器是一个只写变量
"""
import re
from _operator import add

from Init_SparkContext import MySparkContext

sc = MySparkContext().open()

# 累加空行
file = sc.textFile('../test.log')
# 创建Accumulator[int]并初始化为0
blankLines = sc.accumulator(0)


def extractCallSigns(line):
    global blankLines  # 访问全局变量
    if line == "":
        blankLines += 1
    return line.split(" ")


callSigns = file.flatMap(extractCallSigns)
callSigns.saveAsTextFile("callSigns")
print("Blank lines: %d" % blankLines.value)