Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 在线精品自拍,免费播放国产一级,国产一区二区三区久久精品

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          前端:JS延長加載的方式有哪些?

          么是JS延遲加載?

          JS延遲加載,也就是等頁面加載完成之后再加載JavaScript文件

          為什么讓JS實(shí)現(xiàn)延遲加載?

          js的延遲加載有助于提高頁面的加載速度。

          Js延遲加載的方式有哪些?一般有以下幾種方式:

          ·defer屬性

          ·async屬性

          ·動(dòng)態(tài)創(chuàng)建DOM方式

          ·使用jQuery的getScript方法

          ·使用setTimeout延遲方法

          ·讓JS最后加載

          1、defer屬性

          HTML 4.01為<script>標(biāo)簽定義了defer屬性。標(biāo)簽定義了defer屬性元素中設(shè)置defer屬性,等于告訴瀏覽器立即下載,但延遲執(zhí)行標(biāo)簽定義了defer屬性。

          用途:表明腳本在執(zhí)行時(shí)不會(huì)影響頁面的構(gòu)造。也就是說,腳本會(huì)被延遲到整個(gè)頁面都解析完畢之后再執(zhí)行在<script>元素中設(shè)置defer屬性,等于告訴瀏覽器立即下載,但延遲執(zhí)行

          <!DOCTYPE html>
          <html>
          <head>
          	<script src="test1.js" defer="defer"></script>
          	<script src="test2.js" defer="defer"></script>
          </head>
          <body>
          <!--這里放內(nèi)容-->
          </body>
          </html>

          說明:雖然<script>元素放在了<head>元素中,但包含的腳本將延遲瀏覽器遇到</html>標(biāo)簽后再執(zhí)行HTML5規(guī)范要求腳本按照它們出現(xiàn)的先后順序執(zhí)行。在現(xiàn)實(shí)當(dāng)中,延遲腳本并不一定會(huì)按照順序執(zhí)行defer屬性只適用于外部腳本文件。支持HTML5的實(shí)現(xiàn)會(huì)忽略嵌入腳本設(shè)置的defer屬性

          2、async屬性

          HTML5 為<script>標(biāo)簽定義了async屬性。與defer屬性類似,都用于改變處理腳本的行為。同樣,只適用于外部腳本文件。標(biāo)簽定義了async屬性。與defer屬性類似,都用于改變處理腳本的行為。同樣,只適用于外部腳本文件。

          目的:不讓頁面等待腳本下載和執(zhí)行,從而異步加載頁面其他內(nèi)容。異步腳本一定會(huì)在頁面 load 事件前執(zhí)行。不能保證腳本會(huì)按順序執(zhí)行

          <!DOCTYPE html>
          <html>
          	<head>
          		<script src="test1.js" async></script>
          		<script src="test2.js" async></script>
          	</head>
          <body>
          <!--這里放內(nèi)容-->
          </body>
          </html>

          async和defer一樣,都不會(huì)阻塞其他資源下載,所以不會(huì)影響頁面的加載。

          缺點(diǎn):不能控制加載的順序

          3、動(dòng)態(tài)創(chuàng)建DOM方式

          //這些代碼應(yīng)被放置在</ body>標(biāo)簽前(接近HTML文件底部)
          <script type="text/javascript">
          	function downloadJSAtOnload() {
          		varelement = document .createElement("script");
          		element.src = "defer.js";
          		document.body.appendChild(element);
          	}
          	if (window. addEventListener)
          		window.addEventListener("load" ,downloadJSAtOnload, false);
          	else if (window.attachEvent)
          		window.attachEvent("onload", downloadJSAtOnload) ;
          	else
          		window. onload =downloadJSAtOnload;
          </script>

          4、使用jQuery的getScript()方法

          $.getScript("outer.js" , function(){	//回調(diào)函數(shù),成功獲取文件后執(zhí)行的函數(shù)
          	console.log(“腳本加載完成")
          });

          5、使用setTimeout延遲方法的加載時(shí)間延遲加載js代碼,給網(wǎng)頁加載留出更多時(shí)間

          <script type="text/javascript" >
          	function A(){
          		$.post("/1ord/1ogin" ,{name:username,pwd:password},function(){
          			alert("Hello");
          		});
          	}
          	$(function (){
          		setTimeout('A()', 1000);	//延遲1秒
          	})
          </script>

          6、讓JS最后加載

          把js外部引入的文件放到頁面底部,來讓js最后引入,從而加快頁面加載速度例如引入外部js腳本文件時(shí),如果放入html的head中,則頁面加載前該js腳本就會(huì)被加載入頁面,而放入body中,則會(huì)按照頁面從上倒下的加載順序來運(yùn)行JavaScript的代碼。所以我們可以把js外部引入的文件放到頁面底部,來讓js最后引入,從而加快頁面加載速度。

          上述方法2也會(huì)偶爾讓你收到Google頁面速度測試工具的“延遲加載javascript”警告。所以這里的解決方案將是來自Google幫助頁面的推薦方案。

          //這些代碼應(yīng)被放置在</body>標(biāo)簽前(接近HTML文件底部)
          
          <script type= "text/javascript">
          	function downloadJSAtonload() {
          		var element = document.createElement("script");
          		element.src = "defer.js";
          		document.body.appendChild(element);
          	}
          	if (window.addEventListener)
          		window.addEventListener("load", downloadJSAtOnload, false);
          	else if (window.attachEvent )
          		window.attachEvent("onload", downloadJSAtonload);
          	else window.onload = downloadJSAtOnload;
          </script>

          這段代碼意思等到整個(gè)文檔加載完后,再加載外部文件“defer.js”。

          使用此段代碼的步驟:

          6.1)復(fù)制上面代碼

          6.2)粘貼代碼到HTML的標(biāo)簽前 (靠近HTML文件底部)

          6.3)修改“defer.js”為你的外部JS文件名

          6.4)確保文件路徑是正確的。例如:如果你僅輸入“defer.js”,那么“defer.js”文件一定與HTML文件在同一文件夾下。

          注意:

          這段代碼直到文檔加載完才會(huì)加載指定的外部js文件。因此,不應(yīng)該把那些頁面正常加載需要依賴的javascript代碼放在這里。而應(yīng)該將JavaScript代碼分成兩組。一組是因頁面需要而立即加載的javascript代碼,另外一組是在頁面加載后進(jìn)行操作的javascript代碼(例如添加click事件。

          x1 工具準(zhǔn)備

          工欲善其事必先利其器,爬取語料的根基便是基于python。

          我們基于python3進(jìn)行開發(fā),主要使用以下幾個(gè)模塊:requests、lxml、json。

          簡單介紹一個(gè)各模塊的功能

          01|requests

          requests是一個(gè)Python第三方庫,處理URL資源特別方便。它的官方文檔上寫著大大口號(hào):HTTP for Humans(為人類使用HTTP而生)。相比python自帶的urllib使用體驗(yàn),筆者認(rèn)為requests的使用體驗(yàn)比urllib高了一個(gè)數(shù)量級(jí)。

          我們簡單的比較一下:

          urllib:

           1import urllib2
           2import urllib
           3
           4URL_GET = "https://api.douban.com/v2/event/list"
           5#構(gòu)建請求參數(shù)
           6params = urllib.urlencode({'loc':'108288','day_type':'weekend','type':'exhibition'})
           7
           8#發(fā)送請求
           9response = urllib2.urlopen('?'.join([URL_GET,'%s'])%params)
          10#Response Headers
          11print(response.info())
          12#Response Code
          13print(response.getcode())
          14#Response Body
          15print(response.read())
          復(fù)制代碼
          

          requests:

           1import requests
           2
           3URL_GET = "https://api.douban.com/v2/event/list"
           4#構(gòu)建請求參數(shù)
           5params = {'loc':'108288','day_type':'weekend','type':'exhibition'}
           6
           7#發(fā)送請求
           8response = requests.get(URL_GET,params=params)
           9#Response Headers
          10print(response.headers)
          11#Response Code
          12print(response.status_code)
          13#Response Body
          14print(response.text)復(fù)制代碼
          

          我們可以發(fā)現(xiàn),這兩種庫還是有一些區(qū)別的:

          1. 參數(shù)的構(gòu)建:urllib需要對(duì)參數(shù)進(jìn)行urlencode編碼處理,比較麻煩;requests無需額外編碼處理,十分簡潔。

          2. 請求發(fā)送:urllib需要額外對(duì)url參數(shù)進(jìn)行構(gòu)造,變?yōu)榉弦蟮男问?;requests則簡明很多,直接get對(duì)應(yīng)鏈接與參數(shù)。

          3. 連接方式:看一下返回?cái)?shù)據(jù)的頭信息的“connection”,使用urllib庫時(shí),"connection":"close",說明每次請求結(jié)束關(guān)掉socket通道,而使用requests庫使用了urllib3,多次請求重復(fù)使用一個(gè)socket,"connection":"keep-alive",說明多次請求使用一個(gè)連接,消耗更少的資源

          4. 編碼方式:requests庫的編碼方式Accept-Encoding更全,在此不做舉例

          綜上所訴,使用requests更為簡明、易懂,極大的方便我們開發(fā)。

          02|lxml

          BeautifulSoup是一個(gè)庫,而XPath是一種技術(shù),python中最常用的XPath庫是lxml。

          當(dāng)我們拿到requests返回的頁面后,我們怎么拿到想要的數(shù)據(jù)呢?這個(gè)時(shí)候祭出lxml這強(qiáng)大的HTML/XML解析工具。python從不缺解析庫,那么我們?yōu)槭裁匆诒姸鄮炖镞x擇lxml呢?我們選擇另一款出名的HTML解析庫BeautifulSoup來進(jìn)行對(duì)比。

          我們簡單的比較一下:

          BeautifulSoup:

          1from bs4 import BeautifulSoup #導(dǎo)入庫
          2# 假設(shè)html是需要被解析的html
          3
          4#將html傳入BeautifulSoup 的構(gòu)造方法,得到一個(gè)文檔的對(duì)象
          5soup = BeautifulSoup(html,'html.parser',from_encoding='utf-8')
          6#查找所有的h4標(biāo)簽 
          7links = soup.find_all("h4")
          復(fù)制代碼
          

          lxml:

          1from lxml import etree
          2# 假設(shè)html是需要被解析的html
          3
          4#將html傳入etree 的構(gòu)造方法,得到一個(gè)文檔的對(duì)象
          5root = etree.HTML(html)
          6#查找所有的h4標(biāo)簽 
          7links = root.xpath("http://h4")
          復(fù)制代碼
          

          我們可以發(fā)現(xiàn),這兩種庫還是有一些區(qū)別的:

          1. 解析html: BeautifulSoup的解析方式和JQ的寫法類似,API非常人性化,支持css選擇器;lxml的語法有一定的學(xué)習(xí)成本

          2. 性能:BeautifulSoup是基于DOM的,會(huì)載入整個(gè)文檔,解析整個(gè)DOM樹,因此時(shí)間和內(nèi)存開銷都會(huì)大很多;而lxml只會(huì)局部遍歷,另外lxml是用c寫的,而BeautifulSoup是用python寫的,明顯的性能上lxml>>BeautifulSoup。

          綜上所訴,使用BeautifulSoup更為簡明、易用,lxml雖然有一定學(xué)習(xí)成本,但總體也很簡明易懂,最重要的是它基于C編寫,速度快很多,對(duì)于筆者這種強(qiáng)迫癥,自然而然就選lxml啦。

          03|json

          python自帶json庫,對(duì)于基礎(chǔ)的json的處理,自帶庫完全足夠。但是如果你想更偷懶,可以使用第三方j(luò)son庫,常見的有demjson、simplejson。

          這兩種庫,無論是import模塊速度,還是編碼、解碼速度,都是simplejson更勝一籌,再加上兼容性 simplejson 更好。所以大家如果想使用方庫,可以使用simplejson。

          0x2 確定語料源

          將武器準(zhǔn)備好之后,接下來就需要確定爬取方向。

          以電競類語料為例,現(xiàn)在我們要爬電競類相關(guān)語料。大家熟悉的電競平臺(tái)有企鵝電競、企鵝電競和企鵝電競(斜眼),所以我們以企鵝電競上直播的游戲作為數(shù)據(jù)源進(jìn)行爬取。

          我們登陸企鵝電競官網(wǎng),進(jìn)入游戲列表頁,可以發(fā)現(xiàn)頁面上有很多游戲,通過人工去寫這些游戲名收益明顯不高,于是我們就開始我們爬蟲的第一步:游戲列表爬取。


           1import requests
           2from lxml import etree
           3
           4# 更新游戲列表
           5def _updateGameList():
           6 # 發(fā)送HTTP請求時(shí)的HEAD信息,用于偽裝為瀏覽器
           7 heads = { 
           8 'Connection': 'Keep-Alive',
           9 'Accept': 'text/html, application/xhtml+xml, */*',
          10 'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
          11 'Accept-Encoding': 'gzip, deflate',
          12 'User-Agent': 'Mozilla/6.1 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
          13 }
          14 # 需要爬取的游戲列表頁
          15 url = 'https://egame.qq.com/gamelist'
          16
          17 # 不壓縮html,最大鏈接時(shí)間為10妙
          18 res = requests.get(url, headers=heads, verify=False, timeout=10)
          19 # 為防止出錯(cuò),編碼utf-8
          20 res.encoding = 'utf-8'
          21 # 將html構(gòu)建為Xpath模式
          22 root = etree.HTML(res.content)
          23 # 使用Xpath語法,獲取游戲名
          24 gameList = root.xpath("http://ul[@class='livelist-mod']//li//p//text()")
          25 # 輸出爬到的游戲名
          26 print(gameList)
          復(fù)制代碼
          

          當(dāng)我們拿到這幾十個(gè)游戲名后,下一步就是對(duì)這幾十款游戲進(jìn)行語料爬取,這時(shí)候問題就來了,我們要從哪個(gè)網(wǎng)站來爬這幾十個(gè)游戲的攻略呢,taptap?多玩?17173?在對(duì)這幾個(gè)網(wǎng)站進(jìn)行分析后,發(fā)現(xiàn)這些網(wǎng)站僅有一些熱門游戲的文章語料,一些冷門或者低熱度的游戲,例如“靈魂籌碼”、“奇跡:覺醒”、“死神來了”等,很難在這些網(wǎng)站上找到大量文章語料,如圖所示:

          我們可以發(fā)現(xiàn),“ 奇跡:覺醒”、“靈魂籌碼”的文章語料特別少,數(shù)量上不符合我們的要求。 那么有沒有一個(gè)比較通用的資源站,它擁有著無比豐富的文章語料,可以滿足我們的需求。

          其實(shí)靜下心來想想,這個(gè)資源站我們天天都有用到,那就是百度。我們在百度新聞搜索相關(guān)游戲,拿到搜索結(jié)果列表,這些列表的鏈接的網(wǎng)頁內(nèi)容幾乎都與搜索結(jié)果強(qiáng)相關(guān),這樣我們數(shù)據(jù)源不夠豐富的問題便輕松解決了。但是此時(shí)出現(xiàn)了一個(gè)新的問題,并且是一個(gè)比較難解決的問題——如何抓取到任意網(wǎng)頁的文章內(nèi)容?

          因?yàn)椴煌木W(wǎng)站都有不同的頁面結(jié)構(gòu),我們無法與預(yù)知將會(huì)爬到哪個(gè)網(wǎng)站的數(shù)據(jù),并且我們也不可能針對(duì)每一個(gè)網(wǎng)站都去寫一套爬蟲,那樣的工作量簡直難以想象!但是我們也不能簡單粗暴的將頁面中的所有文字都爬下來,用那樣的語料來進(jìn)行訓(xùn)練無疑是噩夢!

          經(jīng)過與各個(gè)網(wǎng)站斗智斗勇、查詢資料與思索之后,終于找到一條比較通用的方案,下面為大家講一講筆者的思路。

          0x3 任意網(wǎng)站的文章語料爬取

          01|提取方法

          1)基于Dom樹正文提取

          2)基于網(wǎng)頁分割找正文塊

          3)基于標(biāo)記窗的正文提取

          4)基于數(shù)據(jù)挖掘或機(jī)器學(xué)習(xí)

          5)基于行塊分布函數(shù)正文提取

          02|提取原理

          大家看到這幾種是不是都有點(diǎn)疑惑了,它們到底是怎么提取的呢?讓筆者慢慢道來。

          1)基于Dom樹的正文提?。?/strong>

          這一種方法主要是通過比較規(guī)范的HTML建立Dom樹,然后地柜遍歷Dom,比較并識(shí)別各種非正文信息,包括廣告、鏈接和非重要節(jié)點(diǎn)信息,將非正文信息抽離之后,余下來的自然就是正文信息。

          但是這種方法有兩個(gè)問題

          ① 特別依賴于HTML的良好結(jié)構(gòu),如果我們爬取到一個(gè)不按W3c規(guī)范的編寫的網(wǎng)頁時(shí),這種方法便不是很適用。

          ② 樹的建立和遍歷時(shí)間復(fù)雜度、空間復(fù)雜度都較高,樹的遍歷方法也因HTML標(biāo)簽會(huì)有不同的差異。

          2) 基于網(wǎng)頁分割找正文塊 :

          這一種方法是利用HTML標(biāo)簽中的分割線以及一些視覺信息(如文字顏色、字體大小、文字信息等)。

          這種方法存在一個(gè)問題:

          ① 不同的網(wǎng)站HTML風(fēng)格迥異,分割沒有辦法統(tǒng)一,無法保證通用性。

          3) 基于標(biāo)記窗的正文提取:

          先科普一個(gè)概念——標(biāo)記窗,我們將兩個(gè)標(biāo)簽以及其內(nèi)部包含的文本合在一起成為一個(gè)標(biāo)記窗(比如 <h1>我是h1</h1> 中的“我是h1”就是標(biāo)記窗內(nèi)容),取出標(biāo)記窗的文字。

          這種方法先取文章標(biāo)題、HTML中所有的標(biāo)記窗,在對(duì)其進(jìn)行分詞。然后計(jì)算標(biāo)題的序列與標(biāo)記窗文本序列的詞語距離L,如果L小于一個(gè)閾值,則認(rèn)為此標(biāo)記窗內(nèi)的文本是正文。

          這種方法雖然看上去挺好,但其實(shí)也是存在問題的:

          ① 需要對(duì)頁面中的所有文本進(jìn)行分詞,效率不高。

          ② 詞語距離的閾值難以確定,不同的文章?lián)碛胁煌拈撝怠?/p>

          4)基于數(shù)據(jù)挖掘或機(jī)器學(xué)習(xí)

          使用大數(shù)據(jù)進(jìn)行訓(xùn)練,讓機(jī)器提取主文本。

          這種方法肯定是極好的,但是它需要先有html與正文數(shù)據(jù),然后進(jìn)行訓(xùn)練。我們在此不進(jìn)行探討。

          5)基于行塊分布函數(shù)正文提取

          對(duì)于任意一個(gè)網(wǎng)頁,它的正文和標(biāo)簽總是雜糅在一起。此方法的核心有亮點(diǎn):① 正文區(qū)的密度;② 行塊的長度;一個(gè)網(wǎng)頁的正文區(qū)域肯定是文字信息分布最密集的區(qū)域之一,這個(gè)區(qū)域可能最大(評(píng)論信息長、正文較短),所以同時(shí)引進(jìn)行塊長度進(jìn)行判斷。

          實(shí)現(xiàn)思路:

          ① 我們先將HTML去標(biāo)簽,只留所有正文,同時(shí)留下標(biāo)簽取出后的所有空白位置信息,我們稱其為Ctext;

          ② 對(duì)每一個(gè)Ctext取周圍k行(k<5),合起來稱為Cblock;

          ③ 對(duì)Cblock去掉所有空白符,其文字總長度稱為Clen;

          ④ 以Ctext為橫坐標(biāo)軸,以各行的Clen為縱軸,建立坐標(biāo)系。

          以這個(gè)網(wǎng)頁為例: http://www.gov.cn/ldhd/2009-11/08/content_1459564.htm 該網(wǎng)頁的正文區(qū)域?yàn)?45行至182行。


          由上圖可知,正確的文本區(qū)域全都是分布函數(shù)圖上含有最值且連續(xù)的一個(gè)區(qū)域,這個(gè)區(qū)域往往含有一個(gè)驟升點(diǎn)和一個(gè)驟降點(diǎn)。因此,網(wǎng)頁正文抽取問題轉(zhuǎn)化為了求行塊分布函數(shù)上的驟升點(diǎn)和驟降點(diǎn)兩個(gè)邊界點(diǎn),這兩個(gè)邊界點(diǎn)所含的區(qū)域包含了當(dāng)前網(wǎng)頁的行塊長度最大值并且是連續(xù)的。

          經(jīng)過大量實(shí)驗(yàn),證明此方法對(duì)于中文網(wǎng)頁的正文提取有較高的準(zhǔn)確度,此算法的優(yōu)點(diǎn)在于,行塊函數(shù)不依賴與HTML代碼,與HTML標(biāo)簽無關(guān),實(shí)現(xiàn)簡單,準(zhǔn)確率較高。

          主要邏輯代碼如下:

           1# 假設(shè)content為已經(jīng)拿到的html
           2
           3# Ctext取周圍k行(k<5),定為3
           4blocksWidth = 3
           5# 每一個(gè)Cblock的長度
           6Ctext_len = []
           7# Ctext
           8lines = content.split('n')
           9# 去空格
          10for i in range(len(lines)):
          11 if lines[i] == ' ' or lines[i] == 'n':
          12 lines[i] = ''
          13# 計(jì)算縱坐標(biāo),每一個(gè)Ctext的長度
          14for i in range(0, len(lines) - blocksWidth):
          15 wordsNum = 0
          16 for j in range(i, i + blocksWidth):
          17 lines[j] = lines[j].replace("\s", "")
          18 wordsNum += len(lines[j])
          19 Ctext_len.append(wordsNum)
          20# 開始標(biāo)識(shí)
          21start = -1
          22# 結(jié)束標(biāo)識(shí)
          23end = -1
          24# 是否開始標(biāo)識(shí)
          25boolstart = False
          26# 是否結(jié)束標(biāo)識(shí)
          27boolend = False
          28# 行塊的長度閾值
          29max_text_len = 88
          30# 文章主內(nèi)容
          31main_text = []
          32# 沒有分割出Ctext
          33if len(Ctext_len) < 3:
          34 return '沒有正文'
          35for i in range(len(Ctext_len) - 3):
          36 # 如果高于這個(gè)閾值
          37 if(Ctext_len[i] > max_text_len and (not boolstart)):
          38 # Cblock下面3個(gè)都不為0,認(rèn)為是正文
          39 if (Ctext_len[i + 1] != 0 or Ctext_len[i + 2] != 0 or Ctext_len[i + 3] != 0):
          40 boolstart = True
          41 start = i
          42 continue
          43 if (boolstart):
          44 # Cblock下面3個(gè)中有0,則結(jié)束
          45 if (Ctext_len[i] == 0 or Ctext_len[i + 1] == 0):
          46 end = i
          47 boolend = True
          48 tmp = []
          49
          50 # 判斷下面還有沒有正文
          51 if(boolend):
          52 for ii in range(start, end + 1):
          53 if(len(lines[ii]) < 5):
          54 continue
          55 tmp.append(lines[ii] + "n")
          56 str = "".join(list(tmp))
          57 # 去掉版權(quán)信息
          58 if ("Copyright" in str or "版權(quán)所有" in str):
          59 continue
          60 main_text.append(str)
          61 boolstart = boolend = False
          62# 返回主內(nèi)容
          63result = "".join(list(main_text))
          復(fù)制代碼
          

          0x4 結(jié)語

          至此我們就可以獲取任意內(nèi)容的文章語料了,但這僅僅是開始,獲取到了這些語料后我們還需要在一次進(jìn)行清洗、分詞、詞性標(biāo)注等,才能獲得真正可以使用的語料。

          本篇文章主要介紹了pandas中對(duì)series和dataframe對(duì)象進(jìn)行連接的方法:pd.append()和pd.concat(),文中通過示例代碼對(duì)這兩種方法進(jìn)行了詳細(xì)的介紹,希望能對(duì)各位python小白的學(xué)習(xí)有所幫助。

          一、df.append(df)

          ? 描述:append方法用以在表尾中添加新的行,并返回追加后的數(shù)據(jù)對(duì)象,若追加的行中存在原數(shù)據(jù)沒有的列,會(huì)新增一列,并用nan填充;若追加的行數(shù)據(jù)中缺少原數(shù)據(jù)某列,同樣以nan填充

          語法:df.append(other, ignore_index=False, verify_integrity=False, sort=None)

          ? 參數(shù)說明:

          • other:要追加的數(shù)據(jù),可以是dataframe,series,字典,列表
          • ignore_index:兩個(gè)表的index是否有實(shí)際含義,默認(rèn)為False,若ignore_index=True,表根據(jù)列名對(duì)齊合并,生成新的index
          • verify_integrity:默認(rèn)為False,若為True,創(chuàng)建具有重復(fù)項(xiàng)的索引時(shí)引發(fā)ValueError
          • sort:默認(rèn)為False,若為True如果’ self ‘和’ other '的列沒有對(duì)齊,則對(duì)列進(jìn)行排序。

          下面對(duì)append方法的每個(gè)參數(shù)進(jìn)行詳細(xì)介紹:

          ? 第一個(gè)參數(shù)為other:要追加的數(shù)據(jù),可以是dataframe,series,字典,列表甚至是元素;但前后類型要一致。

          1. 將數(shù)據(jù)追加到series
          # 將數(shù)據(jù)追加到series
          <<< a=df.iloc[0,:]
          <<< b=df.iloc[6,:]
          <<< a.append(b)      #需賦給新值,不改變原數(shù)組
          A     0
          B     1
          C     2
          D     3
          E     4
          F     5
          A    36
          B    37
          C    38
          D    39
          E    40
          F    41
          dtype: int32
          <<< a
          A    0
          B    1
          C    2
          D    3
          E    4
          F    5
          Name: S1, dtype: int32
          
          <<< c=a.append(b)    # 保存為c
          <<< c
          A     0
          B     1
          C     2
          D     3
          E     4
          F     5
          A    36
          B    37
          C    38
          D    39
          E    40
          F    41
          dtype: int32
          
          1. 將數(shù)據(jù)追加到dataframe
          # 將數(shù)據(jù)追加到dataframe
          <<< a=df.iloc[0:2,:]
          <<< b=df.iloc[4:6,:] 
          <<< c=a.append(b)           # 注意是縱向追加,不支持橫向追加
          <<< c
              A	B	C	D	E   F
          S1	0	1	2	3	4	5
          S2	6	7	8	9	10	11
          S5	24	25	26	27	28	29
          S6	30	31	32	33	34	35
          

          ? 注意:獲取單行得到的結(jié)果是一維數(shù)組,當(dāng)一維數(shù)組[6,:]和二維數(shù)組[2,6]追加時(shí),會(huì)得到8*7的數(shù)組,匹配不上的地方用NA填充。

          # 將二維數(shù)組追加到一維數(shù)組
          <<< a=df.iloc[0,:]
          <<< b=df.iloc[4:6,:] 
          <<< c=a.append(b)          
          <<< c
                0	  A	  B	  C	  D	  E	  F
          A	0.0	NaN	NaN	NaN	NaN	NaN	NaN
          B	1.0	NaN	NaN	NaN	NaN	NaN	NaN
          C	2.0	NaN	NaN	NaN	NaN	NaN	NaN
          D	3.0	NaN	NaN	NaN	NaN	NaN	NaN
          E	4.0	NaN	NaN	NaN	NaN	NaN	NaN
          F	5.0	NaN	NaN	NaN	NaN	NaN	NaN
          S5	NaN	24.0	25.0	26.0	27.0	28.0	29.0
          S6	NaN	30.0	31.0	32.0	33.0	34.0	35.0
          
          1. 將數(shù)據(jù)追加到list
          • list是一維:以列的形式來進(jìn)行追加操作
          • list是二維:以行的形式來進(jìn)行追加操作
          • list是三維:只添加一個(gè)值注意:追加到列表時(shí),是在原數(shù)組改動(dòng),是在原數(shù)組改動(dòng),是在原數(shù)組改動(dòng)
          # 列表追加到列表
          <<< a=[]
          <<< b=df.iloc[6,:].tolist()
          <<< a.append(b)
          <<< a
          [[36, 37, 38, 39, 40, 41]]
          
          # 序列追加到列表
          <<< a=[1,2,3,4,5,6,7]
          <<< b=df.iloc[6,:]
          <<< a.append(b)
          <<< a
          [1, 2, 3, 4, 5, 6, 7, A    36
           B    37
           C    38
           D    39
           E    40
           F    41
           Name: S7, dtype: int32]
          
          1. 追加字典TypeError: Can only append a Series if ignore_index=True or if the Series has a name
          <<< df1=pd.DataFrame()
          <<< a={'A':1,'B':2}
          <<< df1=df1.append(a,ignore_index=True)
          <<< df1
              A	B
          0	1	2
          
          1. 將單個(gè)元素追加到列表

          ? append方法也可以將單個(gè)元素追加到列表(其他對(duì)象不行),會(huì)自動(dòng)將單個(gè)元素轉(zhuǎn)為列表對(duì)象,再進(jìn)行追加操作

          # 單個(gè)元素進(jìn)行追加
          <<< a=[1,2,3,4,5,6,7,8]
          <<< a.append(9)
          <<< a
          [1, 2, 3, 4, 5, 6, 7, 8, 9]
          
          1. 將其他類型對(duì)象追加到dataframe當(dāng)dataframe使用append方法添加series或字典的時(shí)候,必須要設(shè)置name,設(shè)置name名稱將會(huì)作為index的name,否則會(huì)報(bào)錯(cuò)提示:TypeError: Can only append a Series if ignore_index=True or if the Series has a name
          <<< df1=pd.DataFrame()
          <<< ser=pd.Series({"x":1,"y":2},name="a")
          <<< df1=df1.append(ser)
          <<< df1
              x   y
          a	1	2
          

          ? 如果不添加name,也可以添加參數(shù)ignore_index:

          <<< df1=pd.DataFrame()
          <<< ser=pd.Series({"x":1,"y":2})
          <<< df1=df1.append(ser,ignore_index=True)
          <<< df1
              x   y
          a	1	2
          

          ? 第二個(gè)參數(shù):兩個(gè)表的index是否有實(shí)際含義,默認(rèn)ignore_index=False,若為True,表根據(jù)列名對(duì)齊合并,生成新的index。

          <<< a=df.iloc[0:2,:]
          <<< b=df.iloc[4:6,:]
          <<< a.append(b,ignore_index=True)  
              A   B	C   D   E   F
          0	0	1	2	3	4	5
          1	6	7	8	9	10	11
          2	24	25	26	27	28	29
          3	30	31	32	33	34	35
          
          <<< a=df.iloc[0:2,:]
          <<< b=df.iloc[4:6,:]
          <<< a.append(b)
              A	B	C	D	E   F
          S1	0	1	2	3	4	5
          S2	6	7	8	9	10	11
          S5	24	25	26	27	28	29
          S6	30	31	32	33	34	35
          

          ? 在dataframe中,使用append方法進(jìn)行表合并時(shí),二者匹配不上的地方用NAN填充。

          <<< df1=df.copy()
          <<< df2=pd.DataFrame(np.arange(8).reshape(2,4),columns=<<<['s1','s2','s3','s4'])
          <<< df_new=df1.append(df2,ignore_index=True)
          <<< df_new
              A	B	C	D	E	F	S1	S2	s3	s4
          0	0	1	2	3	4	5	NaN	NaN	NaN	NaN
          1	6	7	8	9	10	11	NaN	NaN	NaN	NaN
          2	12	13	14	15	16	17	NaN	NaN	NaN	NaN
          3	18	19	20	21	22	23	NaN	NaN	NaN	NaN
          4	24	25	26	27	28	29	NaN	NaN	NaN	NaN
          5	30	31	32	33	34	35	NaN	NaN	NaN	NaN
          6	36	37	38	39	40	41	NaN	NaN	NaN	NaN
          7	NaN	NaN	NaN	NaN	NaN	NaN	0	1	2	3
          8	NaN	NaN	NaN	NaN	NaN	NaN	4	5	6	7
          

          ? 第三個(gè)參數(shù)為verify_integrity:默認(rèn)為False 參數(shù)用于檢查結(jié)果對(duì)象新連接軸上的索引是否有重復(fù)項(xiàng),有的話引發(fā) ValueError,可以看到這個(gè)參數(shù)的作用與ignore_index 是互斥的。 (如果 ignore_index = True ,則意味著index不能是重復(fù)的,而ignore_index = False ,則意味著index可以是重復(fù)的)

          <<< df1=df.copy()
          <<< df2=pd.DataFrame(np.arange(8).reshape(2,4),columns=   <<< ['G','H','I','J'],index=['S1','S8'],dtype=int)
          <<< pd.set_option('precision',0)
          <<< df_new=df1.append(df2,verify_integrity=False)
          <<< df_new
              A	B	C	D	E	F	G	H	I	J
          S1	0	1	2	3	4	5	NaN	NaN	NaN	NaN
          S2	6	7	8	9	10	11	NaN	NaN	NaN	NaN
          S3	12	13	14	15	16	17	NaN	NaN	NaN	NaN
          S4	18	19	20	21	22	23	NaN	NaN	NaN	NaN
          S5	24	25	26	27	28	29	NaN	NaN	NaN	NaN
          S6	30	31	32	33	34	35	NaN	NaN	NaN	NaN
          S7	36	37	38	39	40	41	NaN	NaN	NaN	NaN
          S1	NaN	NaN	NaN	NaN	NaN	NaN	0	1	2	3
          S8	NaN	NaN	NaN	NaN	NaN	NaN	4	5	6	7
          

          注意:當(dāng)需要連接的兩個(gè)表的index有重復(fù)值時(shí),設(shè)置ignore_index = True則會(huì)報(bào)錯(cuò)。

          ? 第四個(gè)參數(shù)為sort:默認(rèn)是False,該屬性在pandas的0.23.0版本才有,若為True,則對(duì)兩個(gè)表沒匹配上的列名,進(jìn)行排序,若為False,不排序。

          <<< df1=pd.DataFrame(np.arange(8).reshape(2,4),columns=   <<< ['A1','B1','C1','D1'],index=['S1','S2'])
          <<< df2=pd.DataFrame(np.arange(8).reshape(2,4),columns=   <<< ['A2','B2','C2','D2'],index=['S1','S3'])
          <<< pd.set_option('precision',0)
          <<< df_new=df1.append(df2,sort=True)
          <<< df_new
              A1	A2	B1	B2	C1	C2	D1	D2
          S1	0	NaN	1	NaN	2	NaN	3	NaN
          S2	4	NaN	5	NaN	6	NaN	7	NaN
          S1	NaN	0	NaN	1	NaN	2	NaN	3
          S3	NaN	4	NaN	5	NaN	6	NaN	7
          

          二、pd.concat([df_01,df_02])

          ? 描述:concat方法用以將兩個(gè)或多個(gè)pandas對(duì)象根據(jù)軸(橫向/縱向)進(jìn)行拼接,concat函數(shù)是在pandas命名空間下的方法,因此需要通過pd.concat()的方式來引用。

          語法:pd.concat(‘objs’, ‘a(chǎn)xis=0’, “join=‘outer’”, ‘join_axes=None’, ‘ignore_index=False’, ‘keys=None’, ‘levels=None’, ‘names=None’, ‘verify_integrity=False’, ‘sort=None’, ‘copy=True’)

          常用參數(shù):

          • objs:要進(jìn)行拼接的pandas對(duì)象,可用中括號(hào)[]將兩個(gè)或多個(gè)對(duì)象括起來
          • axis:指定對(duì)象按照那個(gè)軸進(jìn)行拼接,默認(rèn)為0(縱向拼接),1為橫向橫向拼接
          • join:拼接的方式,inner為交集,outer為并集
          • join_axes:index的列表,僅在橫向合并時(shí)使用,指明要將數(shù)據(jù)合并入哪個(gè)原表的index。
          • ignore_index:默認(rèn)為False,如果設(shè)置為true,則無視表原來的軸標(biāo)簽,直接合并,合并后生成新的軸標(biāo)簽。
          • keys:表標(biāo)識(shí)的列表,用來區(qū)分合并的表來自哪里。

          下面,將對(duì)concat方法以上各個(gè)參數(shù)進(jìn)行詳細(xì)說明:

          ? 第一個(gè)要學(xué)習(xí)的參數(shù)為objs:要進(jìn)行拼接的pandas對(duì)象,可用中括號(hào)[]將兩個(gè)或多個(gè)對(duì)象括起來。

          1)對(duì)series進(jìn)行拼接

          <<< ser1=pd.Series(np.arange(9))
          <<< ser2=pd.Series(np.arange(9))
          # 對(duì)兩個(gè)series對(duì)象進(jìn)行拼接
          <<< pd.concat([ser1,ser2])
          0    0
          1    1
          2    2
          3    3
          4    4
          5    5
          6    6
          7    7
          8    8
          0    0
          1    1
          2    2
          3    3
          4    4
          5    5
          6    6
          7    7
          8    8
          dtype: int32
          
          1. 對(duì)DataFrame進(jìn)行拼接
          <<< df1=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['A','B','C'],index=['a','b','c'])
          <<< df2=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['D','E','F'],index=['e','f','g'])
          # 對(duì)兩個(gè)DataFrame對(duì)象進(jìn)行拼接
          <<< pd.concat([df1,df2])
              A   B	C	D	E   F
          a	0	1	2	NaN	NaN	NaN
          b	3	4	5	NaN	NaN	NaN
          c	6	7	8	NaN	NaN	NaN
          e	NaN	NaN	NaN	0	1	2
          f	NaN	NaN	NaN	3	4	5
          g	NaN	NaN	NaN	6	7	8
          

          ? 第二個(gè)要學(xué)習(xí)的參數(shù)為axis:指定對(duì)象按照那個(gè)軸進(jìn)行拼接,默認(rèn)為0(縱向拼接),1為橫向橫向拼接。

          <<< df1=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['A','B','C'],index=['a','b','c'])
          <<< df2=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['D','E','F'],index=['a','b','d'])
          # 將數(shù)據(jù)對(duì)象df1和df2沿1軸進(jìn)行拼接,即進(jìn)行橫向拼接
          <<< pd.concat([df1,df2],axis=1)
              A	B	C	D	E	F
          a	0	1	2	0	1	2
          b	3	4	5	3	4	5
          c	6	7	8	NaN	NaN	NaN
          d	NaN	NaN	NaN	6	7	8
          

          ? 注意:當(dāng)對(duì)Series進(jìn)行拼接時(shí),設(shè)置axis=0進(jìn)行縱向拼接的結(jié)果對(duì)象為Series,設(shè)置axis=1進(jìn)行橫向拼接的結(jié)果對(duì)象為DataFrame。

          <<< ser1=pd.Series(np.arange(9))
          <<< ser2=pd.Series(np.arange(9))
          # 對(duì)Series進(jìn)行拼接縱向拼接,結(jié)果認(rèn)為Series對(duì)象
          <<< a=pd.concat([ser1,ser2],axis=0)
          <<< type(a)
          pandas.core.series.Series
          # 對(duì)Series進(jìn)行拼接橫向拼接,結(jié)果轉(zhuǎn)換為DataFrame對(duì)象
          <<< b=pd.concat([ser1,ser2],axis=1)
          <<< type(b)
          pandas.core.frame.DataFrame
          

          ? 第三個(gè)要學(xué)習(xí)的參數(shù)為join:拼接的方式,inner為交集,outer為并集,橫向拼接時(shí)由index的交/并集決定,縱向拼接時(shí)由columns的交/并集決定,同時(shí),如果join=outer,匹配不上的地方以nan填充。

          <<< df1=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['A','B','C'],index=['a','b','c'])
          <<< df2=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['D','E','F'],index=['a','b','d'])
          # 將df1和df2進(jìn)行橫向合并,取二者的并集
          <<< pd.concat([df1,df2],axis=1)
              A	B	C	D	E	F
          a	0	1	2	0	1	2
          b	3	4	5	3	4	5
          c	6	7	8	NaN	NaN	NaN
          d	NaN	NaN	NaN	6	7	8
          # 將df1和df2進(jìn)行橫向合并,只取二者的交集
          <<< pd.concat([df1,df2],axis=1,join='inner')
              A	B	C	D	E	F
          a	0	1	2	0	1	2
          b	3	4	5	3	4	5
          

          ? 第四個(gè)要學(xué)習(xí)的參數(shù)為join_axes:以哪個(gè)數(shù)據(jù)對(duì)象的index/columns作為軸進(jìn)行拼接,當(dāng)進(jìn)行橫向拼接時(shí),join_axes為index的列表,如需根據(jù)df1對(duì)齊數(shù)據(jù),則會(huì)保留df1的index,再將df2的數(shù)據(jù)進(jìn)行拼接;同理,縱向拼接時(shí)為columns的列表。

          <<< df1=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['A','B','C'],index=['a','b','c'])
          <<< df2=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['D','E','F'],index=['a','b','d'])
          # 根據(jù)df1的index對(duì)齊數(shù)據(jù)
          <<< pd.concat([df1,df2],axis=1,join_axes=[df1.index])
              A	B	C	D	E	F
          a	0	1	2	0	1	2
          b	3	4	5	3	4	5
          c	6	7	8	NaN	NaN	NaN
          # 根據(jù)df2的index對(duì)齊數(shù)據(jù)
          <<< pd.concat([df1,df2],axis=1,join_axes=[df2.index])
              A	B	C	D	E	F
          a	0	1	2	0	1	2
          b	3	4	5	3	4	5
          d	NaN	NaN	NaN	6	7	8
          

          ? 第五個(gè)要學(xué)習(xí)的參數(shù)為ignore_index:默認(rèn)為False,如果設(shè)置為true,則無視表原來的軸標(biāo)簽,直接合并,合并后生成新的軸標(biāo)簽。

          ? 這里需要注意的是,與append方法只能進(jìn)行縱向拼接不同,concat方法既可以進(jìn)行橫向拼接,也可以進(jìn)行縱向拼接,若設(shè)置ignore_index=True,當(dāng)進(jìn)行橫向拼接時(shí),則無視原表的columns,直接合并,合并后生成默認(rèn)的columns;同理,當(dāng)進(jìn)行縱向拼接時(shí),則是忽略原表的index,生成新的index。

          <<< df1=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['A','B','C'],index=['a','b','c'])
          <<< df2=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['D','E','F'],index=['a','b','d'])
          # 橫向拼接時(shí),忽略的是columns,index仍起作用
          <<< pd.concat([df1,df2],axis=1,ignore_index=True)
              0	1	2	3	4	5
          a	0	1	2	0	1	2
          b	3	4	5	3	4	5
          c	6	7	8	NaN	NaN	NaN
          d	NaN	NaN	NaN	6	7	8
          # 縱向拼接時(shí),忽略的是index,columns仍起作用
          pd.concat([df1,df2],axis=0,ignore_index=True)
              0	1	2	3	4	5
          a	0	1	2	0	1	2
          b	3	4	5	3	4	5
          c	6	7	8	NaN	NaN	NaN
          d	NaN	NaN	NaN	6	7	8
          

          ? 第六個(gè)要學(xué)習(xí)的參數(shù)為keys:表標(biāo)識(shí)的列表,用來區(qū)分合并后的數(shù)據(jù)來源于哪個(gè)表,當(dāng)ignore_index=True時(shí),此參數(shù)的作用失效。

          <<< df1=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['A','B','C'],index=['a','b','c'])
          <<< df2=pd.DataFrame(np.arange(9).reshape(3,3),columns=   <<< ['D','E','F'],index=['a','b','d'])
          # 設(shè)置ignore_index=True時(shí),參數(shù)keys不起作用
          <<< pd.concat([df1,df2],axis=1,ignore_index=True,keys=    <<< ['df1','df2'])
              0	1	2	3	4	5
          a	0	1	2	0	1	2
          b	3	4	5	3	4	5
          c	6	7	8	NaN	NaN	NaN
          d	NaN	NaN	NaN	6	7	8
          # 設(shè)置ignore_index=False,會(huì)根據(jù)keys的列表標(biāo)識(shí)結(jié)果中的數(shù)據(jù)來源
          <<< pd.concat([df1,df2],axis=1,ignore_index=False,keys=   <<< ['df1','df2'])
              df1	        df2
              A	B	C	D	E	F
          a	0	1	2	0	1	2
          b	3	4	5	3	4	5
          c	6	7	8	NaN	NaN	NaN
          d	NaN	NaN	NaN	6	7	8
          

          總結(jié):

          • append方法只能進(jìn)行橫向拼接,且只支持對(duì)兩個(gè)對(duì)象進(jìn)行拼接操作,但append支持單個(gè)對(duì)象的連接,此方法常用于循環(huán)中;
          • concat方法可用于橫向或縱向的拼接,同時(shí)可以設(shè)置以并集或交集的方式拼接

          如對(duì)append和concat方法還感興趣,建議可前往查看官方文檔:

          1)https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.append.html?highlight=append#pandas.DataFrame.append

          2)pandas.concat - pandas 0.21.0 documentation


          主站蜘蛛池模板: 精品国产不卡一区二区三区| 国产精品视频一区二区噜噜| 久久久久人妻精品一区二区三区 | 国产精品免费视频一区| 亚洲AV日韩综合一区尤物| 亚洲熟妇无码一区二区三区导航| 中文字幕无线码一区二区| 国产一区二区三区四| 色一情一乱一伦一区二区三欧美| 色偷偷一区二区无码视频| 精品一区二区久久久久久久网站| 无码日韩精品一区二区人妻 | 夜夜精品无码一区二区三区| 毛片一区二区三区无码| 亚洲国产精品一区二区三区在线观看| 国产乱码精品一区二区三区中文| 国产综合无码一区二区三区| 冲田杏梨高清无一区二区| 国产aⅴ一区二区三区| 福利一区二区三区视频午夜观看| 国产福利无码一区在线| 亚洲A∨精品一区二区三区下载| 精品国产鲁一鲁一区二区| 亚洲视频一区二区三区四区| 精品香蕉一区二区三区| 亚洲丶国产丶欧美一区二区三区 | 末成年女AV片一区二区| 亚洲欧美成人一区二区三区| 大伊香蕉精品一区视频在线| 精品欧美一区二区在线观看| 亚洲一区二区女搞男| 国产精品一区二区在线观看| 亚洲AV无码一区二区三区DV| 高清一区二区三区| 人妻视频一区二区三区免费| 国产一区二区在线视频| 美女免费视频一区二区| 亚洲色偷精品一区二区三区| 亚洲乱码一区二区三区在线观看| 女人18毛片a级毛片一区二区| 免费无码VA一区二区三区|