PySpark筆記(三):DataFrame
DataFrame是在Spark 1.3中正式引入的一種以RDD為基礎的不可變的分散式資料集,類似於傳統資料庫的二維表格,資料在其中以列的形式被組織儲存。如果熟悉Pandas,其與Pandas DataFrame是非常類似的東西。
DataFrame API受到R和Python(Pandas)中的資料框架的啟發,但是從底層開始設計以支援現代大資料和資料科學應用程式。作為現有RDD API的擴充套件,DataFrame具有以下功能:
能夠從單檯膝上型電腦上的千位元組資料擴充套件到大型群集上的PB級資料
支援各種資料格式和儲存系統
透過Spark SQL Catalyst最佳化器實現最先進的最佳化和程式碼生成
透過Spark無縫整合所有大資料工具和基礎架構
Python,Java,Scala和R的API(透過SparkR開發)
對於熟悉其他程式語言資料框架的新使用者,此API應該讓他們感到賓至如歸。對於現有的Spark使用者,此擴充套件API將使Spark更易於程式設計,同時透過智慧最佳化和程式碼生成來提高效能。
透過DataFrame與Catalyst最佳化器,現有的Spark程式遷移到DataFrame時效能得到改善。由於最佳化器生成用於執行的JVM位元組碼,因此Python使用者將體驗到與Scala和Java使用者相同的高效能。
performance.png
建立DataFrame
Spark中有兩種方式可以將資料從RDD轉化為DataFrame:反射推斷或者程式設計指定。反射推斷是Spark應用程式自動識列的型別,然後透過Spark SQL將行物件的RDD轉換為DataFrame。程式設計指定則是在執行之前,人工從Spark SQL中引入資料型別分配給不同的列。
使用資料結構:
data
普通讀取csv為DataFrames資料。
# 讀取csv為DataFrametraffic = spark.read.csv('E:DocumentsDesktopdata.csv', header='true')# 建立臨時表traffic.createOrReplaceTempView("traffic")# 顯示前10行traffic.show(10)
show
列印表結構,可以看出Spark自動將所有列推斷為string,這不是我們想要的型別。
traffic.printSchema()
schema
透過pandas輔助讀取csv。
import pandas as pd df = pd.read_csv('E:DocumentsDesktopdata.csv') traffic = spark.createDataFrame(df) traffic.createOrReplaceTempView("traffic") traffic.printSchema()
schema
反射推斷
traffic = spark.read.csv('E:DocumentsDesktopdata.csv', header='true', inferSchema='true') traffic.createOrReplaceTempView("traffic") traffic.show(10) traffic.printSchema()
inferSchema屬性用來指示是否使用自動推斷,預設為False。
schema
程式設計指定
儘管自動推斷比較方便,如果啟用了inferSchema,則函式將資料全部讀入以確定輸入模式。要避免遍歷整個資料一次,應該使用模式明確指定模式。
StructField(field, data_type=None, nullable=True, metadata=None)
field – Either the name of the field or a StructField object
data_type – If present, the DataType of the StructField to create
nullable – Whether the field to add should be nullable (default True)
metadata – Any additional metadata (default None)
from pyspark.sql.types import *# 指定DataFrame每個列的模式schema = StructType([... StructField("detectorid", IntegerType()),... StructField("starttime",StringType()),... StructField("volume", IntegerType()),... StructField("speed", FloatType()),... StructField("occupancy", FloatType())])# 使用指定模式讀入traffic = spark.read.csv('E:DocumentsDesktopdata.csv', header='true', schema=schema) traffic.createOrReplaceTempView("traffic") traffic.show(10) traffic.printSchema()
schema
DataFrame查詢
常用API
select()
投影一組表示式並返回一個新的DataFrame。
引數:cols - 列名稱(字串)或表示式(列)的列表。 如果其中一個列名是'*',則該列將展開以包含當前DataFrame中的所有列。
>>> traffic.select("speed").show(5) +-----+|speed|+-----+|56.52||53.54||54.64||54.94||51.65|+-----+ only showing top 5 rows
filter()
使用給定的條件過濾行。where()是filter()的別名。
引數:condition - 型別的一列.BooleanType或一個SQL表示式的字串。
>>> traffic.filter(traffic.speed > 50).show(5) +----------+--------------+------+-----+---------+|detectorid| starttime|volume|speed|occupancy|+----------+--------------+------+-----+---------+| 100625|2015/12/1 0:00| 48|56.52| 1.29|| 100625|2015/12/1 0:15| 50|53.54| 1.48|| 100625|2015/12/1 0:30| 25|54.64| 0.62|| 100625|2015/12/1 0:45| 34|54.94| 0.85|| 100625|2015/12/1 1:00| 23|51.65| 0.6|+----------+--------------+------+-----+---------+ only showing top 5 rows>>> traffic.where(traffic.volume > 50).show(5) +----------+--------------+------+-----+---------+|detectorid| starttime|volume|speed|occupancy|+----------+--------------+------+-----+---------+| 100625|2015/12/1 3:45| 61|57.62| 1.65|| 100625|2015/12/1 4:00| 69| 56.7| 1.89|| 100625|2015/12/1 4:15| 94|56.53| 2.69|| 100625|2015/12/1 4:30| 87|55.53| 2.58|| 100625|2015/12/1 4:45| 161|55.51| 4.62|+----------+--------------+------+-----+---------+ only showing top 5 rows
drop()
返回刪除指定列的新DataFrame。
引數:cols - 要刪除的列的字串名稱,要刪除的列或要刪除的列的字串名稱的列表。
>>> traffic.drop("speed").show(5) +----------+--------------+------+---------+|detectorid| starttime|volume|occupancy| +----------+--------------+------+---------+ | 100625|2015/12/1 0:00| 48| 1.29|| 100625|2015/12/1 0:15| 50| 1.48| | 100625|2015/12/1 0:30| 25| 0.62|| 100625|2015/12/1 0:45| 34| 0.85| | 100625|2015/12/1 1:00| 23| 0.6|+----------+--------------+------+---------+ only showing top 5 rows
cache()
使用預設儲存級別(MEMORY_AND_DISK)持久儲存DataFrame。
traffic.cache()
collect()
以Row列表形式返回所有記錄。
traffic.collect()
show()
將前n行列印到控制檯。
引數:
n - 要顯示的行數。
truncate - 如果設定為True,則預設截斷超過20個字元的字串。 如果設定為大於1的數字,則截斷長字串以截斷長度並將其右對齊。
>>> traffic.show(5) +----------+--------------+------+-----+---------+|detectorid| starttime|volume|speed|occupancy|+----------+--------------+------+-----+---------+| 100625|2015/12/1 0:00| 48|56.52| 1.29|| 100625|2015/12/1 0:15| 50|53.54| 1.48|| 100625|2015/12/1 0:30| 25|54.64| 0.62|| 100625|2015/12/1 0:45| 34|54.94| 0.85|| 100625|2015/12/1 1:00| 23|51.65| 0.6|+----------+--------------+------+-----+---------+ only showing top 5 rows
count()
返回此DataFrame中的行數。
>>> traffic.count()17814
columns
以列表形式返回所有列名稱。
>>> traffic.columns ['detectorid', 'starttime', 'volume', 'speed', 'occupancy']
dtypes
將所有列名稱及其資料型別作為列表返回。
>>> traffic.dtypes [('detectorid', 'int'), ('starttime', 'string'), ('volume', 'int'), ('speed', 'double'), ('occupancy', 'double')]
fillna()
替換的空值,別名na.fill()
。
引數:
value - int,long,float,string或dict。 用來替換空值的值。 如果值是字典,則子集將被忽略,並且值必須是從列名(字串)到替換值的對映。 替換值必須是int,long,float,boolean或string。
子集 - 要考慮的列名稱的可選列表。 子集中指定的不具有匹配資料型別的列將被忽略。 例如,如果value是一個字串,並且子集包含一個非字串列,則非字串列將被忽略。
>>> traffic.na.fill(10)>>> traffic.na.fill({'volume': 0, 'speed': '0'})
corr()
以雙精度值計算DataFrame的兩列的相關性。 目前只支援Pearson Correlation Coefficient。 DataFrame.corr()和DataFrameStatFunctions.corr()是彼此的別名。
引數:
col1 - 第一列的名稱
col2 - 第二列的名稱
方法 - 相關方法。 目前只支援“Pearson”
>>> traffic.corr("volume", "speed") -0.588695158526705
cov()
計算給定列的樣本協方差(由它們的名稱指定)作為雙精度值。 DataFrame.cov()和DataFrameStatFunctions.cov()是別名。
引數:
col1 - 第一列的名稱
col2 - 第二列的名稱
>>> traffic.cov("volume", "speed") -1166.285227777989
describe()
計算數字和字串列的統計資訊。
這包括count,mean,stddev,min和max。 如果未給出列,則此函式將計算所有數字或字串列的統計資訊。
>>> df.describe().show() +-------+--------------+--------------+------------------+------------------+------------------+|summary| detectorid| starttime| volume| speed| occupancy| +-------+--------------+--------------+------------------+------------------+------------------+ | count| 17814| 17814| 17814| 17737| 17814|| mean| 100627.5| null|208.72779836083978| 45.94760105993146|13.775621421354007| | stddev|1.707873064514| null| 129.673023730382|15.010086497913619|13.391984211880049|| min| 100625|2015/12/1 0:00| 0| 1.14| 0.0| | max| 100630|2015/12/9 9:45| 528| 69.33| 73.25|+-------+--------------+--------------+------------------+------------------+------------------+>>> traffic.describe(['speed']).show() +-------+------------------+|summary| speed| +-------+------------------+ | count| 17737|| mean| 45.94760105993146| | stddev|15.010086497913619|| min| 1.14| | max| 69.33|+-------+------------------+
distinct()
返回包含此DataFrame中不同行的新DataFrame。
>>> traffic.distinct().count()17814
createOrReplaceGlobalTempView()
使用給定名稱建立或替換全域性臨時檢視。
此臨時檢視的生命週期與此Spark應用程式相關聯。
>>> traffic.createOrReplaceGlobalTempView("traffic")>>> df = spark.sql("select * from traffic")>>> df.count()17814
createOrReplaceTempView()
使用此DataFrame建立或替換本地臨時檢視。
此臨時表的生命週期與用於建立此DataFrame的SparkSession相關聯。
>>> traffic.createOrReplaceTempView("traffic")>>> df = spark.sql("select * from traffic")>>> df.count()17814
使用SQL查詢
由於建立了臨時表,我們可以對臨時表執行sql操作。
>>> spark.sql("select * from traffic where volume > 50 and speed > 50").show() +----------+---------------+------+-----+---------+|detectorid| starttime|volume|speed|occupancy|+----------+---------------+------+-----+---------+| 100625| 2015/12/1 3:45| 61|57.62| 1.65|| 100625| 2015/12/1 4:00| 69| 56.7| 1.89|| 100625| 2015/12/1 4:15| 94|56.53| 2.69|| 100625| 2015/12/1 4:30| 87|55.53| 2.58|| 100625| 2015/12/1 4:45| 161|55.51| 4.62|| 100625| 2015/12/1 5:00| 203|55.41| 5.96|| 100625| 2015/12/1 5:15| 185|55.14| 6.61|| 100625| 2015/12/1 5:30| 308|52.39| 9.87|| 100625| 2015/12/1 5:45| 343|51.01| 11.49|| 100625|2015/12/1 10:15| 306| 50.6| 11.98|| 100625|2015/12/1 10:30| 334|51.42| 11.53|| 100625|2015/12/1 10:45| 349|52.67| 11.51|| 100625|2015/12/1 11:00| 262|52.36| 10.54|| 100625|2015/12/1 12:00| 255|52.47| 9.36|| 100625|2015/12/1 12:15| 346|50.25| 13.44|| 100625|2015/12/1 12:30| 367| 51.2| 12.47|| 100625|2015/12/1 12:45| 330|52.78| 11.56|| 100625|2015/12/1 13:00| 306|52.36| 12.01|| 100625|2015/12/1 13:30| 371|50.28| 13.93|| 100625|2015/12/1 13:45| 294|50.62| 12.92|+----------+---------------+------+-----+---------+ only showing top 20 rows
Dataset
除了DataFrame,Spark 1.6中還引入了Dataset API,其提供了一種型別安全的物件導向的程式設計介面,但是其只能在Java與Scala中使用。Python不能使用該API的原因是因為其本身不是一種型別安全的語言。在Spark 2.0中DataFrame API被整合入如Dataset API,DataFrame是Dataset未型別化API的一個別名。
未型別化的API:DataFrame = Dataset[Row] 型別化的API:Dataset[T]
作者:洛荷
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3486/viewspace-2818646/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【pyspark】dataframe常用操作Spark
- PySpark DataFrame教程與演示Spark
- 【pandas學習筆記】DataFrame筆記
- Python資料分析 DataFrame 筆記Python筆記
- 邏輯和物理計劃如何工作時讀蜂巢分割槽表在獸人pyspark dataframe嗎Spark
- RUST 筆記(三)Rust筆記
- spring筆記三Spring筆記
- MyBatis筆記(三)MyBatis筆記
- 三匯記錄儀筆記筆記
- 基於python的大資料分析實戰學習筆記-pandas之DataFramePython大資料筆記
- React 學習筆記【三】React筆記
- cmake 學習筆記(三)筆記
- goLang學習筆記(三)Golang筆記
- unity學習筆記(三)Unity筆記
- ONNXRuntime學習筆記(三)筆記
- Python學習筆記(三)Python筆記
- InnoDB文件筆記(三)—— Undo Log筆記
- 多執行緒筆記 三執行緒筆記
- ES 筆記三:基本概念筆記
- Redis學習筆記(三) 字典Redis筆記
- TS學習筆記(三):類筆記
- 刷前端面經筆記(三)前端筆記
- Linux 筆記分享三:Linux 命令Linux筆記
- 紅日靶機(三)筆記筆記
- CANopen學習筆記(三)NMT筆記
- c++學習筆記(三)C++筆記
- react native學習筆記(三)React Native筆記
- RxSwift筆記三組合序列Swift筆記
- pyspark底層淺析Spark
- PySpark 通過Arrow加速Spark
- 用來記筆記的三個 Emacs 模式筆記Mac模式
- Scala - DataFrame
- 架構學習筆記系列三架構筆記
- ES6 學習筆記三筆記
- Spark學習筆記(三)-Spark StreamingSpark筆記
- Falcon(三欄 Markdown 筆記軟體)筆記
- 《人月神話》閱讀筆記三筆記
- Python爬蟲學習筆記(三)Python爬蟲筆記