DataFrame是一種不可變的分佈式數據集。Spark早期的API中,由於JVM和Py4J之間的通信開銷,使用Python執行查詢會明顯變慢。
Python到RDD之間的通信
在PySpark驅動器中,Spark Context通過Py4J啓動一個JavaSparkContext的JVM,所有的RDD轉換最初都映射到Java中的PythonRDD對象。這樣,Python和JVM之間就存在很多上下文切換和通信開銷。
利用DataFrame加速PySpark
DataFrame和Catalyst優化器的意義在於和非優化的RDD查詢比較時增加PySpark的性能,這種查詢性能的提升源於降低了Python和JVM之間的通信開銷。
創建DataFrame
通常情況下,使用SparkSession導入數據來創建DataFrame。
生成JSON數據
stringJSONRDD = sc.parallelize(
("""{"id":"1","name":"a","age":"20"}""",
"""{"id":"2","name":"b","age":"21"}""",
"""{"id":"3","name":"c","age":"22"}""")
)
創建一個DataFrame
peopleJSON = spark.read.json(stringJSONRDD)
創建一個臨時表
peopleJSON = createOrReplaceTempView("peopleJSON")
簡單的DataFrame查詢
DataFrame API查詢
peopleJSON.show()
SQL查詢
spark.sql("select * from peopleJSON").collect() # 查詢表中全部數據
spark.sql("select * from peopleJSON").show(n) # 查詢前n行數據
spark.sql("select * from peopleJSON").take(n) # 查詢第n行數據
RDD的交互操作
使用反射來推斷模式
在DataFrame中,鍵是列,數據類型通過採樣數據來判斷。
# 打印模式
peopleJSON.printSchema()
編程指定模式
# 導入“類型”
from pyspark.sql.types import *
# 生成以逗號分隔的數據
stringCSVRDD = sc.parallelize(
[
(1,"a",20),
(2,"b",21),
(3,"c",22)
])
# 指定模式
schema = StructType(
[
StructField("id",LongType(),True),
StructField("name",StringType(),True),
StructField("age",LongType(),True),
])
# 創建DataFrame
people = spark.createDataFrame(stringCSVRDD, schema)
# 利用DataFrame創建臨時視圖
people.createOrReplaceTempView("people")
利用DataFrame API查詢
行數
可以通過collect、show、take等方法查看DataFrame中的數據。
people.count()
# [Out]: 3
運行篩選語句
使用filter方法進行篩選:
people.select("id", "age").filter("age = 22").show()
# 和下面語句等效
people.select(people.id, people.age).filter(people.age == 22).show()
也可以使用like進行模式匹配:
people.select("name", "age").filter("name like 'a%'").show()
利用SQL查詢
行數
spark.sql("select count(1) from people").show()
利用where語句進行條件篩選
spark.sql("select id, age from people where age = 22").show()
spark.sql("select name, age from people where name like 'a%'").show()
- 更新時間:2018-10-23