Spark大數(shù)據(jù)分析實(shí)務(wù) 課件 項(xiàng)目4 基于Spark SQL實(shí)現(xiàn)廣告流量檢測數(shù)據(jù)探索分析_第1頁
Spark大數(shù)據(jù)分析實(shí)務(wù) 課件 項(xiàng)目4 基于Spark SQL實(shí)現(xiàn)廣告流量檢測數(shù)據(jù)探索分析_第2頁
Spark大數(shù)據(jù)分析實(shí)務(wù) 課件 項(xiàng)目4 基于Spark SQL實(shí)現(xiàn)廣告流量檢測數(shù)據(jù)探索分析_第3頁
Spark大數(shù)據(jù)分析實(shí)務(wù) 課件 項(xiàng)目4 基于Spark SQL實(shí)現(xiàn)廣告流量檢測數(shù)據(jù)探索分析_第4頁
Spark大數(shù)據(jù)分析實(shí)務(wù) 課件 項(xiàng)目4 基于Spark SQL實(shí)現(xiàn)廣告流量檢測數(shù)據(jù)探索分析_第5頁
已閱讀5頁,還剩103頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

基于SparkSQL實(shí)現(xiàn)廣告流量檢測數(shù)據(jù)探索分析知識準(zhǔn)備教學(xué)目標(biāo)知識目標(biāo)了解SparkSQL框架的功能及運(yùn)行過程。了解SparkSQL與Shell交互。掌握SparkSQL的可編程數(shù)據(jù)模型DataFrame的創(chuàng)建、查詢等操作方法。教學(xué)目標(biāo)技能目標(biāo)能夠配置SparkSQLCLI,提供SparkSQL與Shell交互環(huán)境。能夠通過不同數(shù)據(jù)源創(chuàng)建DataFrame。能夠?qū)崿F(xiàn)DataFrame數(shù)據(jù)及行列表的查詢操作。教學(xué)目標(biāo)素質(zhì)目標(biāo)具備鉆研刻苦的精神,通過學(xué)習(xí)SparkSQLCLI,能夠獨(dú)立完成配置SparkonHive環(huán)境。具備獨(dú)立思考的學(xué)習(xí)能力,通過學(xué)習(xí)編程數(shù)據(jù)模型DataFrame,掌握多種方式創(chuàng)建DataFrame。具備良好的創(chuàng)新能力,通過學(xué)習(xí)DataFrame的查詢操作,掌握探索廣告流量檢測數(shù)據(jù)的分析能力。思維導(dǎo)圖項(xiàng)目背景數(shù)據(jù)探索分析可通過對數(shù)據(jù)的整理、清洗、可視化和統(tǒng)計(jì)分析等手段,發(fā)現(xiàn)數(shù)據(jù)中的模式、趨勢和關(guān)聯(lián)性,從而幫助人們理解數(shù)據(jù)背后的信息和規(guī)律,為決策提供支持和指導(dǎo)。為建設(shè)更高水平的平安中國,需堅(jiān)持以網(wǎng)絡(luò)安全為基礎(chǔ)等內(nèi)容的新安全格局,強(qiáng)化國家戰(zhàn)略科技力量,保障新發(fā)展格局。廣告數(shù)據(jù)監(jiān)測公司希望通過SparkSQL技術(shù)實(shí)現(xiàn)廣告流量檢測數(shù)據(jù)探索分析,主要從數(shù)據(jù)記錄數(shù)、數(shù)據(jù)缺失值和字段特征進(jìn)行探索,了解廣告流量檢測數(shù)據(jù)的整體情況與大體質(zhì)量,為后續(xù)數(shù)據(jù)預(yù)處理提供處理憑證,并且為數(shù)據(jù)挖掘分析結(jié)論有效性和準(zhǔn)確性奠定基礎(chǔ)。項(xiàng)目目標(biāo)根據(jù)存儲(chǔ)在Hive中的廣告流量檢測數(shù)據(jù),使用SparkSQL中的SQL函數(shù)進(jìn)行讀取、查詢、探索分析廣告流量檢測數(shù)據(jù)。目標(biāo)分析讀取Hive中的表并創(chuàng)建DataFrame對象。簡單查詢DataFrame數(shù)據(jù),簡單分析廣告流量檢測數(shù)據(jù)的記錄數(shù)及缺失值等情況。利用分組查詢函數(shù),探索分析廣告流量檢測數(shù)據(jù)中的日流量特征。利用排序查詢函數(shù),探索分析廣告流量檢測數(shù)據(jù)中的IP地址的訪問次數(shù)特征。利用分組查詢函數(shù),探索分析廣告流量檢測數(shù)據(jù)中違規(guī)流量數(shù)據(jù)特征。認(rèn)識SparkSQL框架創(chuàng)建DataFrame對象查看DataFrame數(shù)據(jù)掌握DataFrame行列表查詢操作認(rèn)識SparkSQL框架SparkSQL在Spark內(nèi)核(Core)基礎(chǔ)上提供了對結(jié)構(gòu)化數(shù)據(jù)的處理。所謂結(jié)構(gòu)化數(shù)據(jù),就是每條記錄共用的已知的字段集合。當(dāng)數(shù)據(jù)符合條件時(shí),SparkSOL就會(huì)針對數(shù)據(jù)的讀取和查詢變得更加簡單高效。SparkSQL簡介SparkSQL是一個(gè)用于處理結(jié)構(gòu)化數(shù)據(jù)的框架,可被視為一個(gè)分布式的SQL查詢引擎,提供了一個(gè)抽象的可編程數(shù)據(jù)模型DataFrame。SparkSQL框架的前身是Shark框架,由于Shark需要依賴于Hive而制約了Spark各個(gè)組件的相互集成,所以Spark團(tuán)隊(duì)提出了SparkSQL項(xiàng)目。SparkSQL借鑒了Shark的優(yōu)點(diǎn)同時(shí)擺脫了對Hive的依賴性。相對于Shark,SparkSQL在數(shù)據(jù)兼容、性能優(yōu)化、組件擴(kuò)展等方面更有優(yōu)勢。SparkSQL簡介SparkSQL提供了以下三大功能,如下。SparkSQL簡介具體來說,SparkSQL提供了以下三大功能,如下。SparkSQL可以從各種結(jié)構(gòu)化數(shù)據(jù)源(如JSON、Hive、Parquet等)中讀取數(shù)據(jù)。SparkSQL不僅支持通過spark-shell在Spark程序內(nèi)使用SQL語句進(jìn)行數(shù)據(jù)查詢,也支持類似商業(yè)智能軟件Tableau外部工具、應(yīng)用程序等通過標(biāo)準(zhǔn)數(shù)據(jù)庫連接器(JDBC/ODBC)連接SparkSQL進(jìn)行查詢。當(dāng)在Spark程序內(nèi)使用SparkSQL時(shí),SparkSQL支持SQL與常規(guī)的Python/Java/Scala代碼高度整合,包括連接RDD與SQL表、公開的自定義SQL函數(shù)接口等。SparkSQL簡介為了實(shí)現(xiàn)以上的功能,SparkSQL提供了一種特殊的RDD,叫作SchemaRDD。SchemaRDD是存放Row對象的RDD,每個(gè)Row對象代表一行記錄。SchemaRDD還包含記錄的結(jié)構(gòu)信息(即數(shù)據(jù)字段)。SchemaRDD看起來和普通的RDD很像,但是在內(nèi)部,SchemaRDD可以利用結(jié)構(gòu)信息更加高效地存儲(chǔ)數(shù)據(jù)。SparkSQL簡介此外,SchemaRDD還支持RDD上所沒有的一些新操作,如運(yùn)行SQL查詢。SchemaRDD可以從外部數(shù)據(jù)源創(chuàng)建,也可以從查詢結(jié)果或普通RDD中創(chuàng)建。從Spark1.3.0版本開始,SchemaRDD更名為DataFrame。SparkSQL簡介SparkSQL的運(yùn)行過程如圖所示。SparkSQL簡介DataFrame是一個(gè)分布式的Row對象的數(shù)據(jù)集合,該數(shù)據(jù)集合提供了由列組成的詳細(xì)模式信息,并且DataFrame實(shí)現(xiàn)了RDD的絕大多數(shù)功能。SparkSQL通過SQLContext或HiveContext對象提供的方法可從外部數(shù)據(jù)源如Parquent文件、JSON文件、RDDs、Hive表等加載數(shù)據(jù)創(chuàng)建DataFrame。再通過DataFrame提供的API接口、DSL(領(lǐng)域特定語言)、spark-sql、spark-shell或ThriftJDBC/ODBCserver等方式對DataFrame數(shù)據(jù)進(jìn)行查詢、轉(zhuǎn)換的操作,并將結(jié)果進(jìn)行展現(xiàn)或使用save()、saveAsTable()方法將結(jié)果存儲(chǔ)為不同格式的文件。配置SparkSQLCLIApacheHive是Hadoop上的SQL引擎,SparkSOL編譯時(shí)可以包含Hive支持,也可以不包含。包含Hive支持的SparkSOL可以支持Hive表訪問、UDF(用戶自定義函數(shù))、SerDe(序列化格式和反序列化格式),以及Hive查詢語言。從Spark1.1版本開始,Spark增加了SparkSQLCLI和ThriftJDBC/ODBCserver功能,使得Hive的用戶與熟悉SQL語句的數(shù)據(jù)庫管理員更容易上手。配置SparkSQLCLI即使沒有部署好與Hive的交互,SparkSQL也可以運(yùn)行。若使用SparkSQLCLI的方式訪問操作Hive表數(shù)據(jù),則需要將SparkSQL連接至一個(gè)部署成功的Hive上。配置SparkSQLCLI的基本流程如圖所示。配置SparkSQLCLI配置SparkSQLCLI的具體步驟如下。復(fù)制hive-site.xml文件至Spark安裝目錄的conf目錄。將hive-site.xml復(fù)制至/usr/local/spark-3.2.1-bin-hadoop2.7/conf目錄下。配置MySQL驅(qū)動(dòng),在/usr/local/spark-3.2.1-bin-hadoop2.7/conf/spark-env.sh文件中配置MySQL驅(qū)動(dòng),使用的MySQL驅(qū)動(dòng)包為mysql-connector-java-8.0.21.jar,具體操作如下。配置spark-env.sh文件。進(jìn)入Spark安裝目錄的conf目錄,使用“vimspark-env.sh”命令打開spark-env.sh文件,在文件末尾添加MySQL驅(qū)動(dòng)信息。配置SparkSQLCLI復(fù)制MySQL驅(qū)動(dòng)包至Spark安裝目錄的jars目錄。將MySQL驅(qū)動(dòng)包復(fù)制至Spark安裝目錄的jars目錄下。啟動(dòng)相應(yīng)的集群與服務(wù)。啟動(dòng)Hadoop集群、啟動(dòng)MySQL服務(wù)和Hive的元數(shù)據(jù)服務(wù)。修改日志級別。將conf目錄下的perties.template文件復(fù)制并重命名為perties,執(zhí)行命令“vimperties”打開perties文件,修改SparkSQL運(yùn)行時(shí)的日志級別,將文件中“l(fā)og4j.rootCategory”的值修改為“WARN,console”。配置SparkSQLCLI啟動(dòng)Spark集群。切換至Spark安裝目錄的/sbin目錄,執(zhí)行命令“./start-all.sh”啟動(dòng)Spark集群。SparkSQL與Shell交互SparkSQL框架其實(shí)已經(jīng)集成在spark-shell中,因此,啟動(dòng)spark-shell即可使用SparkSQL的Shell交互接口。SparkSQL查詢數(shù)據(jù)時(shí)可以使用兩個(gè)對象,即SQLContext和HiveContext,從Spark2.x版本開始,Spark將SQLContext和HiveContext進(jìn)行整合,提供一種全新的編程接口——SparkSession。SparkSQL與Shell交互SparkSession也稱為上下文,是與SparkSQL交互的主要入口點(diǎn),用于處理與SQL相關(guān)的任務(wù)。SparkSession封裝了之前版本的SparkConf、SparkContext和SQLContext,提供了許多方便的方法來簡化Spark編程。而SparkContext是SparkCore的上下文,是整個(gè)Spark應(yīng)用程序的基礎(chǔ),負(fù)責(zé)與集群管理器通信以及執(zhí)行RDD操作。SparkSQL與Shell交互如果在spark-shell中執(zhí)行SQL語句,那么需要使用SparkSession對象調(diào)用sql()方法。在spark-shell啟動(dòng)的過程中會(huì)初始化SparkSession對象為spark,此時(shí)初始化的spark對象既支持SQL語法解析器,也支持HQL語法解析器,也就是使用spark可以執(zhí)行SQL語句和HQL語句。SparkSQL與Shell交互讀者也可以自己聲明SQLContext對象,創(chuàng)建SQLContext對象。但通過SQLContext創(chuàng)建的對象只能執(zhí)行SQL語句,不能執(zhí)行HQL語句。使用HiveContext之前首先需要確認(rèn)使用的Spark版本是支持Hive的,并且已配置SparkSQLCLI。與使用SQLContext一樣,使用HiveContext之前可以先創(chuàng)建一個(gè)HiveContext對象。認(rèn)識SparkSQL框架創(chuàng)建DataFrame對象查看DataFrame數(shù)據(jù)掌握DataFrame行列表查詢操作創(chuàng)建DataFrame對象DataFrame對象可以通過結(jié)構(gòu)化數(shù)據(jù)文件、外部數(shù)據(jù)庫、Spark計(jì)算過程中生成的RDD、Hive中的表等數(shù)據(jù)源進(jìn)行創(chuàng)建。雖然數(shù)據(jù)源存在多種,但創(chuàng)建DataFrame對象的流程是類似的,學(xué)習(xí)過程中要以辯證的思維看待問題,學(xué)會(huì)辯證統(tǒng)一,才能真正掌握創(chuàng)建DataFrame對象的方法。結(jié)構(gòu)化數(shù)據(jù)源創(chuàng)建DataFrame一般情況下,結(jié)構(gòu)化數(shù)據(jù)文件存儲(chǔ)在HDFS中,較為常見的結(jié)構(gòu)化數(shù)據(jù)文件格式是Parquet格式或JSON格式。通過結(jié)構(gòu)化數(shù)據(jù)源創(chuàng)建DataFrame的方法如下。通過Parquet格式文件創(chuàng)建DataFrame。SparkSQL可以通過load()方法將HDFS上的結(jié)構(gòu)化數(shù)據(jù)文件轉(zhuǎn)換為DataFrame,load()方法默認(rèn)導(dǎo)入的文件格式是Parquet。通過Parquet格式文件創(chuàng)建DataFrame的基本流程如下。將Parquret文件上傳至HDFS。將/usr/local/spark-3.2.1-bin-hadoop2.7/examples/src/main/resources/目錄下的users.parquret文件上傳至HDFS的/user/root/SparkSQL目錄下。結(jié)構(gòu)化數(shù)據(jù)源創(chuàng)建DataFrame加載Parquet文件創(chuàng)建DataFrame。在spark-shell界面中,加載HDFS上的users.parquet文件數(shù)據(jù)并轉(zhuǎn)換為DataFrame。從運(yùn)行結(jié)果中可以看出,dfParquet存在name、favorite_color等3個(gè)字段。結(jié)構(gòu)化數(shù)據(jù)源創(chuàng)建DataFrame通過JSON格式文件創(chuàng)建DataFrame。若加載JSON格式的文件數(shù)據(jù)轉(zhuǎn)換為DataFrame,則還需要使用format()方法。通過JSON格式文件創(chuàng)建DataFrame的基本流程如下。將Json文件上傳至HDFS。將/usr/local/spark-3.2.1-bin-hadoop2.7/examples/src/main/resources/目錄下的employees.json文件上傳至HDFS的/user/root/SparkSQL目錄下。結(jié)構(gòu)化數(shù)據(jù)源創(chuàng)建DataFrame加載JSON文件創(chuàng)建DataFrame。在spark-shell界面中,使用format()方法和load()方法加載HDFS上的employees.json文件數(shù)據(jù)并轉(zhuǎn)換為DataFrame。從如圖所示的運(yùn)行結(jié)果中可以看出,dfJson存在name、salary兩個(gè)字段。外部數(shù)據(jù)庫創(chuàng)建DataFrameSparkSQL可以讀取關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)并使用SQL查詢。首先需要將關(guān)系型數(shù)據(jù)庫表加載成DataFrame,然后DataFrame注冊成視圖使用SQL查詢。以MySQL數(shù)據(jù)庫的表數(shù)據(jù)為例,將MySQL數(shù)據(jù)庫test中的student表的數(shù)據(jù),讀者需要將“user”“password”對應(yīng)的值修改為實(shí)際進(jìn)入MySQL數(shù)據(jù)庫時(shí)的賬戶名稱和密碼。RDD創(chuàng)建DataFrameSparkSQL也可以對普通RDD的數(shù)據(jù)使用SQL查詢。RDD是彈性分布式數(shù)據(jù)集,是Spark核心底層操作的數(shù)據(jù)類型,Spark批處理底層操作的數(shù)據(jù)類型就是RDD。RDD數(shù)據(jù)轉(zhuǎn)為DataFrame有兩種方式。RDD創(chuàng)建DataFrame第一種方式是利用反射機(jī)制推斷RDD模式,再創(chuàng)建DataFrame,基本流程如圖所示。RDD創(chuàng)建DataFrame利用反射機(jī)制推斷RDD模式,再創(chuàng)建DataFrame,步驟如下。將/usr/local/spark-3.2.1-bin-hadoop2.7/examples/src/main/resources/目錄下的people.txt文件上傳至HDFS的/user/root/SparkSQL目錄下。讀取HDFS上的people.txt文件。加載成String類型的RDD。自定義Person樣例類。將得到的String類型的RDD轉(zhuǎn)換成Person類型的RDD。將Person類型的RDD通過隱式轉(zhuǎn)換函數(shù)轉(zhuǎn)換成DataFrame。RDD創(chuàng)建DataFrame第二種方式是采用編程指定Schema的方式,通過動(dòng)態(tài)創(chuàng)建Schema的方式將RDD轉(zhuǎn)換成DataFrame,基本流程如圖所示。通過動(dòng)態(tài)創(chuàng)建Schema的方式將RDD轉(zhuǎn)換成DataFrame,步驟如下。將HDFS上的people.txt文件轉(zhuǎn)換為String類型的RDD。將String類型的RDD轉(zhuǎn)換成Row類型的RDD。創(chuàng)建列的Schema信息。將Row類型的RDD根據(jù)列的Schema信息映射為DataFrame。Hive中的表創(chuàng)建DataFrame使用SparkSession對象并調(diào)用sql()方法查詢Hive中的表數(shù)據(jù)并轉(zhuǎn)換成DataFrame,查詢weather數(shù)據(jù)庫中的weather_in表數(shù)據(jù)并轉(zhuǎn)換成DataFrame,創(chuàng)建結(jié)果如圖所示。認(rèn)識SparkSQL框架創(chuàng)建DataFrame對象查看DataFrame數(shù)據(jù)掌握DataFrame行列表查詢操作查看DataFrame數(shù)據(jù)DataFrame派生于RDD,因此類似于RDD,DataFrame只有在提交Action操作時(shí)才進(jìn)行計(jì)算。DataFrame查看及獲取數(shù)據(jù)常用的函數(shù)或方法如表所示。函數(shù)或方法描述printSchema()打印數(shù)據(jù)模式show()查看數(shù)據(jù)first()/head()/take()/takeAsList()獲取collect()/collectAsList()獲取所有數(shù)據(jù)查看DataFrame數(shù)據(jù)將/usr/local/spark-3.2.1-bin-hadoop2.7/examples/src/main/resources/目錄下的people.txt文件上傳至HDFS的/user/root/SparkSQL目錄下。堅(jiān)持在發(fā)展中保障和改善民生,鼓勵(lì)共同奮斗創(chuàng)造美好生活,不斷實(shí)現(xiàn)人民對美好生活的向往。隨著人們生活質(zhì)量的提高,人們開始注重享受美好生活,其中逛街、看電影等成為常見的選擇。查看DataFrame數(shù)據(jù)現(xiàn)有一份用戶對電影評分的數(shù)據(jù)ratings.csv和電影數(shù)據(jù)movie.csv,字段說明如表所示。為了更好地滿足人們對電影的需求,需要對上述兩份電影數(shù)據(jù)進(jìn)行分析,幫助了解用戶對電影的興趣和喜好。數(shù)據(jù)文件字段名說明movie.csvmovieId電影IDtitle電影名稱Genres電影類型ratings.csvuserId用戶IDmovieId電影IDrating用戶對電影的評分timestamp時(shí)間戳查看DataFrame數(shù)據(jù)將兩份數(shù)據(jù)上傳至HDFS,加載movie.csv數(shù)據(jù)創(chuàng)建DataFrame對象movies,加載ratings.csv數(shù)據(jù)創(chuàng)建DataFrame對象ratings。通過查看DataFrame數(shù)據(jù),可以了解數(shù)據(jù)的屬性及數(shù)據(jù)的格式。創(chuàng)建DataFrame對象后,可以去查看DataFrame數(shù)據(jù)的模式。使用printSchema函數(shù)可以查看DataFrame數(shù)據(jù)模式,打印出列的名稱和類型。printSchema():打印數(shù)據(jù)模式查看DataFrame對象ratings的數(shù)據(jù)模式,查看結(jié)果。將/usr/local/spark-3.2.1-bin-hadoop2.7/examples/src/main/resources/目錄下的people.txt文件上傳至HDFS的/user/root/SparkSQL目錄下。show():查看數(shù)據(jù)使用show()方法可以查看DataFrame數(shù)據(jù),可輸入的參數(shù)及結(jié)果說明。方法 說明show()顯示前20條記錄show(numRows:Int)顯示numRows條記錄show(truncate:Boolean)是否最多只顯示20個(gè)字符,默認(rèn)為trueshow(numRows:Int,truncate:Boolean)顯示numRows條記錄并設(shè)置過長字符串的顯示格式show():查看數(shù)據(jù)使用show()方法查看DataFrame對象ratings中的數(shù)據(jù),show()方法與show(true)方法查詢的結(jié)果一樣,只顯示前20條記錄,最多只顯示20個(gè)字符。查看結(jié)果。創(chuàng)建DataFrame對象show()方法默認(rèn)只顯示前20行記錄。若需要查看前n行記錄則可以使用show(numRows:Int)方法,如通過“ratings.show(5)”命令查看對象ratings的前5行記錄。first()/head()/take()/takeAsList():獲取若干行記錄獲取DataFrame若干行記錄除了使用show()方法之外,還可以使用first()、head()、take()、takeAsList()方法,DataFrame獲取若干行記錄的方法解釋說明。方法 說明first()獲取第一行記錄head(n:Int)獲取前n行記錄take(n:Int)獲取前n行記錄takeAsList(n:Int)獲取前n行數(shù)據(jù),并以List的形式展現(xiàn)first()/head()/take()/takeAsList():獲取若干行記錄分別使用first()、head()、take()、takeAsList()方法查看對象ratings前幾行數(shù)據(jù)記錄。first()和head()方法的功能相同,以Row或Array[Row]的形式返回一行或多行數(shù)據(jù)。take()和takeAsList()方法則會(huì)將獲得的數(shù)據(jù)返回驅(qū)動(dòng)程序,為避免驅(qū)動(dòng)程序發(fā)生內(nèi)存溢出錯(cuò)誤(OutofMemoryError),數(shù)據(jù)量比較大時(shí)不建議使用。first()/head()/take()/takeAsList():獲取若干行記錄collect()方法可以查詢DataFrame中所有的數(shù)據(jù),并返回一個(gè)Array對象,collectAsList()方法和collect()方法類似,可以查詢DataFrame中所有的數(shù)據(jù),但是返回的是List對象。分別使用collect()和collectAsList()方法即可查看ratings所有數(shù)據(jù)。認(rèn)識SparkSQL框架創(chuàng)建DataFrame對象查看DataFrame數(shù)據(jù)掌握DataFrame行列表查詢操作掌握DataFrame行列表查詢操作DataFrame查詢數(shù)據(jù)有兩種方法,第一種是將DataFrame注冊成為臨時(shí)表,再通過SQL語句查詢數(shù)據(jù)。在代碼414中已創(chuàng)建了DataFrame對象dfPerson,將dfPerson注冊成臨時(shí)表,使用spark.sql()方法查詢dfPerson中年齡大于20的用戶,如代碼所示,查詢結(jié)果如圖所示。掌握DataFrame行列表查詢操作第二種方法是直接在DataFrame對象上進(jìn)行查詢。DataFrame提供了很多查詢數(shù)據(jù)的方法,類似于SparkRDD的轉(zhuǎn)換操作,DataFrame的查詢操作是一個(gè)懶操作,即運(yùn)行后僅僅生成一個(gè)查詢計(jì)劃,只有觸發(fā)執(zhí)行操作才會(huì)進(jìn)行計(jì)算并返回結(jié)果。DataFrame常用的查詢方法如表所示。方法描述where()/filter()條件查詢select()/selectExpr()/col()/apply()查詢指定字段的數(shù)據(jù)信息limit(n)查詢前n行記錄orderby()/sort()排序查詢groupBy()分組查詢join()聯(lián)合表查詢where():查詢符合指定條件的數(shù)據(jù)DataFrame可以使用where(conditionExpr:string)方法查詢符合指定條件的數(shù)據(jù),參數(shù)中可以使用and或or。where()方法的返回結(jié)果仍然為DataFrame類型。查詢r(jià)atings對象中電影ID為306且評分大于3的電影評分信息,使用show()方法顯示前3條查詢結(jié)果。filter():篩選符合條件的數(shù)據(jù)DataFrame還可以使用filter()方法篩選出符合條件的數(shù)據(jù),filter()的使用方法和where()是一樣的。使用filter()方法查詢r(jià)atings對象中電影ID為306且評分大于3的電影評分信息,查詢結(jié)果如圖所示,結(jié)果與圖所示的查詢結(jié)果一致。查詢指定字段的數(shù)據(jù)信息在生活中,做成一件事的方法不止一種,人生選擇的路也不止一條等著大家去發(fā)現(xiàn)。所謂條條大路通羅馬,完成目標(biāo)的方法有很多,能有多一種方法的掌握,便能多一條“去羅馬的路”。指定的數(shù)據(jù)信息可以通過多種方法查詢,其中where()和filter()方法查詢的數(shù)據(jù)包含的是所有字段的信息,但是有時(shí)用戶只需要查詢某些字段的值即可。DataFrame提供了查詢指定字段的值的方法,如select()、selectExpr()、col()和apply()方法,用法介紹如下。select()方法:獲取指定字段值select()方法根據(jù)傳入的String類型字段名獲取指定字段的值,并返回一個(gè)DataFrame對象。查詢r(jià)atings對象中movieId和rating字段的數(shù)據(jù),結(jié)果如圖所示。selectExpr()方法:對指定字段進(jìn)行特殊處理在實(shí)際業(yè)務(wù)中,可能需要對某些字段進(jìn)行特殊處理,如為某個(gè)字段取別名、對某個(gè)字段的數(shù)據(jù)進(jìn)行四舍五入等。DataFrame提供了selectExpr()方法,可以對某個(gè)字段指定別名進(jìn)行其他處理。使用selectExpr方法查詢r(jià)atings對象中movieId和rating字段信息,查詢結(jié)果如圖所示。col()/apply():獲取一個(gè)指定字段值col()和apply()方法也可以獲取DataFrame指定字段,但只能獲取一個(gè)字段,并且返回的是一個(gè)Column類型的對象。分別使用col()和apply()方法查詢user對象中zip字段的數(shù)據(jù),查詢結(jié)果如圖所示。查詢指定行數(shù)的數(shù)據(jù)limit()方法可以獲取指定DataFrame數(shù)據(jù)的前n行記錄,不同于take()與head()方法,limit()方法不是Action操作,因此并不會(huì)直接返回查詢結(jié)果,需要結(jié)合show()方法或其他Action操作才可以顯示結(jié)果。使用limit()方法查詢r(jià)atings對象的前3行記錄,并使用show()方法顯示查詢結(jié)果,查詢結(jié)果如圖所示。排序查詢orderBy()方法是根據(jù)指定字段進(jìn)行排序,默認(rèn)為升序排序。若要求降序排序,orderBy()方法的參數(shù)可以使用desc("字段名稱")或$"字段名稱".desc,也可以在指定字段前面加“-”。使用orderBy()方法根據(jù)userId字段對ratings對象進(jìn)行降序排序,查詢結(jié)果如圖所示。排序查詢sort()方法也可以根據(jù)指定字段對數(shù)據(jù)進(jìn)行排序,用法與orderBy()方法一樣。使用sort()方法根據(jù)userId字段對ratings對象進(jìn)行升序排序。分組查詢使用groupBy()方法可以根據(jù)指定字段進(jìn)行分組操作。groupBy()方法的輸入?yún)?shù)既可以傳入String類型的字段名,也可以傳入Column類型的對象。使用groupBy()方法根據(jù)movieId字段對ratings對象進(jìn)行分組。groupBy()方法返回的是一個(gè)GroupedData對象,GroupedData對象可調(diào)用的方法及解釋說明。方法描述max(colNames:String)獲取分組中指定字段或所有的數(shù)值類型字段的最大值min(colNames:String)獲取分組中指定字段或所有的數(shù)值類型字段的最小值mean(colNames:String)獲取分組中指定字段或所有的數(shù)值類型字段的平均值sum(colNames:String)獲取分組中指定字段或所有的數(shù)值類型字段的值的和count()獲取分組中的元素個(gè)數(shù)分組查詢表的方法都可以用在groupBy()方法之后。根據(jù)movieId字段對ratings對象進(jìn)行分組,并計(jì)算分組中的元素個(gè)數(shù),結(jié)果如圖所示。基于SparkSQL實(shí)現(xiàn)廣告流量檢測數(shù)據(jù)探索分析項(xiàng)目實(shí)施讀取數(shù)據(jù)創(chuàng)建DataFrame對象簡單查詢DataFrame數(shù)據(jù)分組查詢?nèi)樟髁刻卣髋判虿樵僆P地址的訪問次數(shù)特征

探索違規(guī)流量數(shù)據(jù)特征讀取數(shù)據(jù)創(chuàng)建DataFrame對象要想對廣告流量檢測數(shù)據(jù)進(jìn)行探索分析,需先通過SparkSQL讀取項(xiàng)目3保存到Hive中表的廣告流量檢測數(shù)據(jù),并創(chuàng)建DataFrame。在知識準(zhǔn)備中讀取Hive中的表創(chuàng)建DataFrame已經(jīng)介紹了相關(guān)的配置步驟。Hive環(huán)境準(zhǔn)備完成后,即可從Hive中讀取數(shù)據(jù)后創(chuàng)建DataFrame。讀取數(shù)據(jù)創(chuàng)建DataFrame對象簡單查詢DataFrame數(shù)據(jù)分組查詢?nèi)樟髁刻卣髋判虿樵僆P地址的訪問次數(shù)特征

探索違規(guī)流量數(shù)據(jù)特征簡單查詢DataFrame數(shù)據(jù)基礎(chǔ)數(shù)據(jù)探索是數(shù)據(jù)挖掘的基礎(chǔ)工作。通過查詢數(shù)據(jù)記錄來了解流量檢測數(shù)據(jù)的數(shù)據(jù)量。查詢數(shù)據(jù)記錄數(shù)通過統(tǒng)計(jì)數(shù)據(jù)總記錄數(shù)及IP地址數(shù)量進(jìn)行簡單的分析,探索7天流量數(shù)據(jù)的數(shù)據(jù)量。查詢數(shù)據(jù)總記錄數(shù)案例的數(shù)據(jù)是7天流量數(shù)據(jù)的數(shù)據(jù)量,第一步就是需要探索7天的數(shù)據(jù)量,查詢結(jié)構(gòu)如圖所示。查詢數(shù)據(jù)記錄數(shù)統(tǒng)計(jì)IP地址的數(shù)量在廣告檢測流量數(shù)據(jù)中,字段ip記錄了流量數(shù)據(jù)提取的IP地址。通過統(tǒng)計(jì)IP地址數(shù)量,可得到ip字段的記錄數(shù)與7天的總記錄是否一致。統(tǒng)計(jì)IP地址的數(shù)量運(yùn)行結(jié)果如圖所示,可知IP地址的記錄數(shù)與數(shù)據(jù)總記錄數(shù)一致,可得IP地址不存在缺失數(shù)據(jù)。簡單查詢DataFrame數(shù)據(jù)查詢數(shù)據(jù)缺失值數(shù)據(jù)質(zhì)量分析是數(shù)據(jù)預(yù)處理的前提,也是數(shù)據(jù)挖掘分析結(jié)論有效性和準(zhǔn)確性的基礎(chǔ),主要任務(wù)是檢查原始數(shù)據(jù)中是否存在臟數(shù)據(jù),臟數(shù)據(jù)一般是指不符合要求,以及不能直接進(jìn)行分析的數(shù)據(jù),包括缺失值、不一致值等。本節(jié)主要通過缺失數(shù)據(jù)及冗余數(shù)據(jù)分析廣告流量數(shù)據(jù)是否存在臟數(shù)據(jù)。對數(shù)據(jù)進(jìn)行質(zhì)量分析首先需考慮數(shù)據(jù)是否存在缺失情況,因此,對7天所有的廣告檢測中的流量數(shù)據(jù)進(jìn)行缺失值探索,統(tǒng)計(jì)出各個(gè)屬性的缺失率,統(tǒng)計(jì)各個(gè)屬性的缺失結(jié)果如圖所示。查詢數(shù)據(jù)缺失值根據(jù)如圖所示的各屬性的缺失率繪制柱形圖,如圖所示,mac、creativeid、mobile_os、mobile_type、app_key_md5、app_name_md5、os_type、idfa、imei、android、openudid等屬性的缺失率非常高。尤其是creativeid屬性,高達(dá)98.39%,由于原始數(shù)據(jù)存在字符型數(shù)據(jù),無法進(jìn)行插補(bǔ),后續(xù)編寫程序,對部分缺失過多的屬性進(jìn)行刪除操作。查詢數(shù)據(jù)缺失值如果缺失值占數(shù)據(jù)集的較大比例,可能無法獲得全面和準(zhǔn)確的數(shù)據(jù)視圖,從而影響分析結(jié)果的可靠性。缺失值的存在可能導(dǎo)致數(shù)據(jù)的不一致性,對數(shù)據(jù)進(jìn)行觀察,其中idfa、imei、android、openudid四個(gè)字段都是用于識別手機(jī)系統(tǒng)類型的屬性,對后續(xù)建模存在較大的影響,四個(gè)字段的分析結(jié)果如表所示。在數(shù)據(jù)缺失的統(tǒng)計(jì)中,數(shù)據(jù)集中idfa、imei、android、openudid四個(gè)字段各自的缺失率是偏高的,若后續(xù)構(gòu)建特征時(shí)需要使用識別手機(jī)系統(tǒng)類型的字段,可以將四個(gè)字段合并,以降低手機(jī)系統(tǒng)類型屬性缺失率,提取有效信息。屬性名稱缺失率備注idfa92.19%可用于識別iOS用戶imei79.83%可用于識別Android用戶android80.79%可用于識別Android用戶openudid84.14%可用于識別iOS用戶讀取數(shù)據(jù)創(chuàng)建DataFrame對象簡單查詢DataFrame數(shù)據(jù)分組查詢?nèi)樟髁刻卣髋判虿樵僆P地址的訪問次數(shù)特征探索違規(guī)流量數(shù)據(jù)特征分組查詢?nèi)樟髁刻卣鲝V告檢測流量數(shù)據(jù)記錄總共有7天,通過字段dt記錄了流量數(shù)據(jù)提取的相對時(shí)間。字段的值為1~7,1表示提取的7天流量數(shù)據(jù)的第一天數(shù)據(jù),以此類推。對每天的數(shù)據(jù)流量數(shù)進(jìn)行統(tǒng)計(jì),查看是否有異常現(xiàn)象。分組統(tǒng)計(jì)流量數(shù)據(jù)的運(yùn)行結(jié)果如圖所示,可以看出數(shù)據(jù)的日流量差異不大,說明并沒有存在數(shù)據(jù)異常增加或減少的情況,數(shù)據(jù)產(chǎn)生的環(huán)境相對穩(wěn)定。讀取數(shù)據(jù)創(chuàng)建DataFrame對象簡單查詢DataFrame數(shù)據(jù)分組查詢?nèi)樟髁刻卣髋判虿樵僆P地址的訪問次數(shù)特征探索違規(guī)流量數(shù)據(jù)特征排序查詢IP地址的訪問次數(shù)特征在廣告檢測流量數(shù)據(jù)樣本數(shù)據(jù)中,每個(gè)記錄數(shù)都記錄了對應(yīng)的IP地址,對點(diǎn)擊的IP進(jìn)行一個(gè)簡單的統(tǒng)計(jì),并根據(jù)統(tǒng)計(jì)數(shù)進(jìn)行排序,查看IP是否存在異常。如圖結(jié)果所示,IP訪問次數(shù)中存在異常值,存在同一個(gè)IP高頻訪問廣告的情況,同時(shí)占據(jù)著很高的數(shù)據(jù)比例,在后續(xù)違規(guī)探索中需對ip字段進(jìn)行一個(gè)估量。讀取數(shù)據(jù)創(chuàng)建DataFrame對象簡單查詢DataFrame數(shù)據(jù)分組查詢?nèi)樟髁刻卣髋判虿樵僆P地址的訪問次數(shù)特征探索違規(guī)流量數(shù)據(jù)特征探索違規(guī)流量數(shù)據(jù)特征不同違規(guī)行為產(chǎn)生的數(shù)據(jù)特征不同,對虛假流量數(shù)據(jù)探索分析,將虛假流量根據(jù)違規(guī)行為進(jìn)行劃分,為構(gòu)建特征指標(biāo)提供保障。虛假流量根據(jù)違規(guī)行為劃分如下:腳本刷新網(wǎng)頁違規(guī)定期清除Cookie,刷新網(wǎng)頁違規(guī)ADSL重新?lián)芴柡笏⑿戮W(wǎng)頁違規(guī)腳本刷新網(wǎng)頁違規(guī)腳本刷新網(wǎng)頁違規(guī)是通過設(shè)定程序,使電腦按一定的規(guī)則訪問目標(biāo)網(wǎng)站。該違規(guī)方式產(chǎn)生的數(shù)據(jù)記錄中Cookie與IP不變,且存在多條記錄。例如,某用戶(IP為1,Cookie為646d9cd31ae2a674d1ed6d68acc6e019)在第1天利用同一瀏覽器(useragent:Mozilla)多次訪問某一網(wǎng)址(mediaid:151)上的廣告(placementid:e886beb3cc63365cf71e1ae19aae60ea)。經(jīng)過統(tǒng)計(jì),產(chǎn)生了1206條Cookie和IP不變的數(shù)據(jù)記錄,該用戶的行為屬于利用腳本刷新網(wǎng)頁的違規(guī)行為,所產(chǎn)生的流量數(shù)據(jù)為虛假流量。對Cookie和IP不變的數(shù)據(jù)記錄進(jìn)行分組統(tǒng)計(jì),探索Cookie和IP不變的數(shù)據(jù)記錄統(tǒng)計(jì)次數(shù)。腳本刷新網(wǎng)頁違規(guī)Cookie和IP相同的流量記錄數(shù)統(tǒng)計(jì)結(jié)果如圖所示,在7天的流量數(shù)據(jù)中,確實(shí)存在同一IP和Cookie高頻點(diǎn)擊廣告的情況。正常情況下極少會(huì)有人在7天內(nèi)頻繁點(diǎn)擊某廣告多達(dá)100次或以上,因此在IP和Cookie不變的情況下,統(tǒng)計(jì)單擊頻數(shù)超過100次的IP和Cookie數(shù)。腳本刷新網(wǎng)頁違規(guī)單擊頻數(shù)超過1000次的IP和Cookie數(shù)統(tǒng)計(jì)結(jié)果如圖所示。7天中同一個(gè)IP和Cookie點(diǎn)擊廣告超過100的就有104個(gè),將同一個(gè)IP和Cookie的對應(yīng)記錄數(shù)相加,在流量記錄中占據(jù)很大比例,如果不加以識別,將會(huì)對廣告主造成很大損失。定期清除Cookie,刷新網(wǎng)頁違規(guī)同一IP和Cookie瀏覽數(shù)據(jù)很容易被識別出來,所以違規(guī)者往往也會(huì)通過定期清除Cookie,產(chǎn)生新的Cookie,制造不同Cookie的訪問記錄,使流量數(shù)據(jù)避免被廣告主識別為虛假流量,該類的虛假流量表現(xiàn)為IP不變,多條不同Cookie記錄。例如,某用戶(IP為92)的流量記錄有10000條,其中含有9000不同的Cookie,該用戶的流量數(shù)據(jù)是通過定期清除Cookie,刷新網(wǎng)頁產(chǎn)生的虛假流量。定期清除Cookie,刷新網(wǎng)頁違規(guī)根據(jù)IP進(jìn)行分組統(tǒng)計(jì),統(tǒng)計(jì)每個(gè)IP對應(yīng)的不同Cookie次數(shù)的分布情況,如圖所示。每個(gè)IP對應(yīng)的不同Cookie次數(shù)的分布情況如圖所示,存在同一個(gè)IP高頻訪問廣告的情況,同時(shí)占據(jù)著很高的數(shù)據(jù)比例,需要進(jìn)行識別。ADSL重新?lián)芴柡笏⑿戮W(wǎng)頁違規(guī)違規(guī)者利用ADSL重新?lián)芴柡笏⑿戮W(wǎng)頁違規(guī),在某一時(shí)間段里,多條訪問記錄的IP來源于同個(gè)區(qū)域,IP的前兩段或前三段相同,此類行為下產(chǎn)生的流量數(shù)據(jù)同樣為虛假流量。例如,前兩段為97.200的IP共20000條,其中前三段為97.200.183的IP有5000條,前三段為97.200.72的IP有15000條。區(qū)域辦公可能會(huì)導(dǎo)致用戶IP的前兩段或三段相同,但是上萬條的流量記錄超出了正常范圍,是違規(guī)者利用ADSL重新?lián)芴柡笏⑿戮W(wǎng)頁的違規(guī)行為。根據(jù)IP前兩段進(jìn)行分組統(tǒng)計(jì),統(tǒng)計(jì)IP前兩段相同的記錄數(shù)的分布情況。ADSL重新?lián)芴柡笏⑿戮W(wǎng)頁違規(guī)IP前兩段相同的記錄數(shù)的分布情況如圖所示,IP前兩段相同的流量記錄上萬的情況比較多,是屬于虛假流量數(shù)據(jù)。ADSL重新?lián)芴柡笏⑿戮W(wǎng)頁違規(guī)根據(jù)IP前三段進(jìn)行分組統(tǒng)計(jì),統(tǒng)計(jì)IP前三段相同的記錄數(shù)的分布情況。IP前三段相同的記錄數(shù)的分布情況如圖所示,IP前三段相同的流量記錄上萬的情況也較多,與IP前兩段相同一樣,如果對應(yīng)的記錄過于龐大,那么定義為虛假流量數(shù)據(jù)。不同的違規(guī)行為產(chǎn)生的數(shù)據(jù)特征不同,對數(shù)據(jù)進(jìn)行探索分析,合理歸納虛假流量的數(shù)據(jù)特征,為后期有針對性地對數(shù)據(jù)進(jìn)行預(yù)處理,構(gòu)建相應(yīng)的指標(biāo)提供可靠依據(jù),可有效提高模型分類的準(zhǔn)確率。項(xiàng)目總結(jié)本項(xiàng)目首先介紹了SparkSQL的功能及運(yùn)行流程,并介紹了SparkSQLCLI的配置方法和SparkSQL與Sheel交互,接著介紹了SparkSQL的抽象的編程數(shù)據(jù)模型DataFrame,詳細(xì)介紹了從結(jié)構(gòu)化數(shù)據(jù)源、外部數(shù)據(jù)庫、RDD及Hive中的表4種方式創(chuàng)建DataFrame對象,最后介紹了DataFrame數(shù)據(jù)的查看以及DataFrame的行列表查詢操作。基于知識點(diǎn)介紹,對廣告流量檢測數(shù)據(jù)創(chuàng)建DataFrame,通過DataFrame的查詢操作對廣告流量檢測數(shù)據(jù)進(jìn)行基本數(shù)據(jù)查詢、缺失數(shù)據(jù)分析以及特征字段進(jìn)行探索分析。通過本項(xiàng)目數(shù)據(jù)探索的結(jié)果,夠更好的開展后續(xù)的數(shù)據(jù)挖掘與數(shù)據(jù)建模工作。基于SparkSQL實(shí)現(xiàn)廣告流量檢測數(shù)據(jù)探索分析技能拓展+測試題技能拓展深度學(xué)習(xí)、勇于實(shí)踐是增強(qiáng)本領(lǐng)的重要途徑,通過多方面深度學(xué)習(xí)來不斷更新知識、更新技能,進(jìn)而提高個(gè)人水平。DataFrame是一種以RDD為基礎(chǔ)的帶有Schema元信息的分布式數(shù)據(jù)集。RDD其實(shí)就是分布式的元素集合。在Spark中,對數(shù)據(jù)的所有操作不外乎創(chuàng)建RDD、轉(zhuǎn)化已有RDD以及調(diào)用RDD操作進(jìn)行求值。而在背后中,Spark會(huì)自動(dòng)將RDD中的數(shù)據(jù)分發(fā)到集群上,并將操作并行化執(zhí)行。RDD的創(chuàng)建Spark提供了兩種創(chuàng)建RDD的方式:讀取外部數(shù)據(jù)集,以及在驅(qū)動(dòng)器程序中對一個(gè)集合進(jìn)行并行化。創(chuàng)建RDD最簡單的方式就是將程序中一個(gè)已有的集合傳給SparkContext的parallelize()方法,可以在Shell中快速創(chuàng)建出RDD,然后對RDD進(jìn)行操作。不過,需要注意的是,除了開發(fā)原型和測試時(shí),此方式用得并不多,原因是需要將整個(gè)數(shù)據(jù)集先放在一臺(tái)機(jī)器的內(nèi)存中。RDD的操作RDD支持兩種操作:轉(zhuǎn)換操作和行動(dòng)操作。RDD的轉(zhuǎn)化操作是返回一個(gè)新的RDD的操作,如map()和filter()方法,而行動(dòng)操作則是向驅(qū)動(dòng)器程序返回結(jié)果或?qū)⒔Y(jié)果寫入外部系統(tǒng)的操作,會(huì)觸發(fā)實(shí)際的計(jì)算,如count()和first()方法。轉(zhuǎn)換操作RDD的轉(zhuǎn)換操作是返回新RDD的操作。轉(zhuǎn)換出來的RDD是惰性求值的,只有在行動(dòng)操作中用到RDD時(shí)才會(huì)被計(jì)算。這樣的設(shè)計(jì)使得Spark可以更高效地執(zhí)行計(jì)算任務(wù),避免了不必要的計(jì)算和數(shù)據(jù)移動(dòng)。假定篩選電影評論數(shù)據(jù)電影類型包含Comedy的電影,可以使用轉(zhuǎn)化操作filter()。RDD的操作行動(dòng)操作行動(dòng)操作是第二種類型的RDD操作,會(huì)將最終求得的結(jié)果返回到驅(qū)動(dòng)器程序,或?qū)懭胪獠看鎯?chǔ)系統(tǒng)中。由于行動(dòng)操作需要生成實(shí)際的輸出,會(huì)強(qiáng)制執(zhí)行求值必須用到的RDD的轉(zhuǎn)化操作。如想輸出數(shù)據(jù)信息,需要使用兩個(gè)行動(dòng)操作來實(shí)現(xiàn),用count()來返回計(jì)數(shù)結(jié)果,用take()來收集RDD中的一些元素,其輸出結(jié)果如圖所示。知識測試(1)下列關(guān)于SparkSQL框架的描述錯(cuò)誤的是()。A.SparkSQL可以從各種結(jié)構(gòu)化數(shù)據(jù)源(如JSON、Hive、Parquet等)中讀取數(shù)據(jù)。B.SparkSQL提供了一種特殊的RDD,叫作DataFrame。C.SparkSQL不僅支持通過spark-shell在Spark程序內(nèi)使用SQL語句進(jìn)行數(shù)據(jù)查詢。D.SparkSQL是一個(gè)用于處理結(jié)構(gòu)化數(shù)據(jù)的框架,可被視為一個(gè)分布式的SQL查詢引擎,提供了一個(gè)抽象的可編程數(shù)據(jù)模型RDD。(2)【多選題】下列關(guān)于DataFrame對象說法正確的是()。A.DataFrame可以通過結(jié)構(gòu)化數(shù)據(jù)文件、外部數(shù)據(jù)庫、Spark計(jì)算過程中生成的RDD、Hive中的表等數(shù)據(jù)源進(jìn)行創(chuàng)建B.加載JSON文件

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論