PySpark初見

PySpark

PySpark 是 Spark 為 Python 開發者提供的 API。

  • 子模塊

    pyspark.sql 模塊

    pyspark.streaming 模塊

    pyspark.ml 包

    pyspark.mllib 包、

  • PySpark 提供的類

    • pyspark.SparkConf

    ? pyspark.SparkConf 類提供了對一個 Spark 應用程序配置的操作方法。用于將各種Spark參數設置為鍵值對。

    • pyspark.SparkContext

    ? pyspark.SparkContext 類提供了應用與 Spark 交互的主入口點,表示應用與 Spark 集群的連接,基于這個連接,應用可以在該集群上創建 RDD 和 廣播變量 (pyspark.Broadcast)

    • pyspark.SparkFiles、

    ? SparkFiles 只包含類方法,開發者不應創建 SparkFiles 類的實例[2]

    • pyspark.RDD

    ? 這個類是為 PySpark 操作 RDD???????????????? 提供了基礎方法[1]

    ? first() 是 pyspark.RDD 類提供的方法,返回 RDD 的第一個元素。

    ? aggregate() 方法使用給定的組合函數和中性“零值,先聚合每個分區的元素,然后再聚合所有分區的結果。

    ? cache() 使用默認存儲級別(MEMORY_ONLY)對此 RDD 進行持久化[3]

    ? collect() 返回一個列表,包含此 RDD 中所有元素[3]

    • pyspark.Accumulator

    ? 一種“只允許添加”的共享變量,Spark 任務只能向其添加值[1]

    • pyspark.Broadcast

    ? Spark 提供了兩種共享變量[3] :廣播變量 和 累加器,pyspark.Broadcast 類提供了對廣播變量的操作方法。

    • pyspark.Accumulator

    ? pyspark.Accumulator 提供了對累加器變量的操作方法[3]

    ? 累加器是僅僅被相關操作累加的變量,因此可以在并行中被有效地支持。

#python 2
text=sc.textFile("shakespare.txt")
print text
for operator import add
def tokenize(text):
    return text.split()
words = text.flatMap(tokenize)
print words
wc = words.map(lambda x: (x,1))
print wc.toDebugString()
counts = wc.reduceBykey(add)
counts.saveAsTextFile("wc")

Spark應用基本模板

## Spark Application - execute with spark-submit
## Imports
from pyspark import SparkConf, SparkContext
## Module Constants
APP_NAME = "My Spark Application"
## Closure Functions
## Main functionality
def main(sc):
    pass
if __name__ == "__main__":
    # Configure Spark
    conf = SparkConf().setAppName(APP_NAME)
    conf = conf.setMaster("local[*]")
    sc   = SparkContext(conf=conf)
    # Execute Main functionality
    main(sc)

下面這段代碼做了什么呢搜索?app.py同目錄下的ontime目錄下的2個CSV文件。最終結果顯示,4月的總延誤時間(單位分鐘),既有早點的(如果你從美國大陸飛往夏威夷或者阿拉斯加),但對大部分大型航空公司都是延誤的。注意,我們在app.py中使用matplotlib直接將結果可視化出來了:

## Spark Application - execute with spark-submit
## Imports
import csv
import matplotlib.pyplot as plt
from StringIO import StringIO
from datetime import datetime
from collections import namedtuple
from operator import add, itemgetter
from pyspark import SparkConf, SparkContext
## Module Constants
APP_NAME = "Flight Delay Analysis"
DATE_FMT = "%Y-%m-%d"
TIME_FMT = "%H%M"
fields   = ('date', 'airline', 'flightnum', 'origin', 'dest', 'dep',
            'dep_delay', 'arv', 'arv_delay', 'airtime', 'distance')
Flight   = namedtuple('Flight', fields)
## Closure Functions
def parse(row):
    """
    Parses a row and returns a named tuple.
    """
    row[0]  = datetime.strptime(row[0], DATE_FMT).date()
    row[5]  = datetime.strptime(row[5], TIME_FMT).time()
    row[6]  = float(row[6])
    row[7]  = datetime.strptime(row[7], TIME_FMT).time()
    row[8]  = float(row[8])
    row[9]  = float(row[9])
    row[10] = float(row[10])
    return Flight(*row[:11])
def split(line):
    """
    Operator function for splitting a line with csv module
    """
    reader = csv.reader(StringIO(line))
    return reader.next()
def plot(delays):
    """
    Show a bar chart of the total delay per airline
    """
    airlines = [d[0] for d in delays]
    minutes  = [d[1] for d in delays]
    index    = list(xrange(len(airlines)))

    fig, axe = plt.subplots()
    bars = axe.barh(index, minutes)

    # Add the total minutes to the right
    for idx, air, min in zip(index, airlines, minutes):
        if min > 0:
            bars[idx].set_color('#d9230f')
            axe.annotate(" %0.0f min" % min, xy=(min+1, idx+0.5), va='center')
        else:
            bars[idx].set_color('#469408')
            axe.annotate(" %0.0f min" % min, xy=(10, idx+0.5), va='center')

    # Set the ticks
    ticks = plt.yticks([idx+ 0.5 for idx in index], airlines)
    xt = plt.xticks()[0]
    plt.xticks(xt, [' '] * len(xt))

    # minimize chart junk
    plt.grid(axis = 'x', color ='white', linestyle='-')

    plt.title('Total Minutes Delayed per Airline')
    plt.show()

## Main functionality
def main(sc):
    # Load the airlines lookup dictionary
    airlines = dict(sc.textFile("ontime/airlines.csv").map(split).collect())
    # Broadcast the lookup dictionary to the cluster
    airline_lookup = sc.broadcast(airlines)
    # Read the CSV Data into an RDD
    flights = sc.textFile("ontime/flights.csv").map(split).map(parse)
    # Map the total delay to the airline (joined using the broadcast value)
    delays  = flights.map(lambda f: (airline_lookup.value[f.airline],
                                     add(f.dep_delay, f.arv_delay)))

    # Reduce the total delay for the month to the airline
    delays  = delays.reduceByKey(add).collect()
    delays  = sorted(delays, key=itemgetter(1))

    # Provide output from the driver
    for d in delays:
        print "%0.0f minutes delayed\t%s" % (d[1], d[0])

    # Show a bar chart of the delays
    plot(delays)

if __name__ == "__main__":
    # Configure Spark
    conf = SparkConf().setMaster("local[*]")
    conf = conf.setAppName(APP_NAME)
    sc   = SparkContext(conf=conf)

    # Execute Main functionality
    main(sc)

Spark不能解決分布式存儲問題(通常Spark從HDFS中獲取數據),但是它為分布式計算提供了豐富的函數式編程API。這個框架建立在伸縮分布式數據集(RDD)之上。RDD是種編程抽象,代表被分區的對象集合,允許進行分布式操作。RDD有容錯能力(可伸縮的部分),更重要的時,可以存儲到節點上的worker內存里進行立即重用。內存存儲提供了快速和簡單表示的迭代算法,以及實時交互分析

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容