版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
目錄
1引言1
1.1項(xiàng)目背景1
1.2開發(fā)環(huán)境與工具1
1.2.1Python簡(jiǎn)介1
1.2.2Pandas簡(jiǎn)介1
1.2.3Pyecharts簡(jiǎn)介2
2需求分析2
2.1可行性需求分析2
2.2采集目標(biāo)功能分析2
2.3關(guān)鍵技術(shù)分析2
2.3.1網(wǎng)絡(luò)爬蟲技術(shù)2
2.3.2文件存取技術(shù)3
2.3.3可視化技術(shù)3
3數(shù)據(jù)采集3
3.1采集頁(yè)面分析3
3.2反爬策略分析4
3.3多線程實(shí)現(xiàn)6
3.4翻頁(yè)實(shí)現(xiàn)8
3.5解析房源信息9
3.6保存到j(luò)son文件10
3.7運(yùn)行爬蟲程序10
4數(shù)據(jù)清洗與處理11
4.1數(shù)據(jù)清洗需求12
4.2數(shù)據(jù)讀取與處理12
4.3數(shù)據(jù)清洗13
4.4數(shù)據(jù)清洗結(jié)果15
5數(shù)據(jù)統(tǒng)計(jì)與分析15
I
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
5.1數(shù)據(jù)分析說明15
5.2數(shù)據(jù)展示15
5.2.1統(tǒng)計(jì)各區(qū)的房源數(shù)量和平均價(jià)格15
5.2.2統(tǒng)計(jì)不同朝向與樓層的房源數(shù)量與價(jià)格18
5.2.3統(tǒng)計(jì)各裝修風(fēng)格的數(shù)量20
5.2.4統(tǒng)計(jì)每年建造的房屋數(shù)量與價(jià)格21
5.3綜述23
6小結(jié)23
參考資料24
II
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
鏈家房產(chǎn)網(wǎng)站北京二手房數(shù)據(jù)采集與分析
1引言
北京作為中國(guó)的首都和經(jīng)濟(jì)中心,房地產(chǎn)市場(chǎng)一直備受關(guān)注。對(duì)于購(gòu)房者
而言,了解房?jī)r(jià)走勢(shì)、房源數(shù)量和房源質(zhì)量是做出購(gòu)房決策的重要參考因素。
而二手房市場(chǎng)則更加反映了房地產(chǎn)市場(chǎng)的真實(shí)情況,因此對(duì)于二手房市場(chǎng)的數(shù)
據(jù)采集和分析也具有很大的實(shí)用價(jià)值。
1.1項(xiàng)目背景
本畢業(yè)設(shè)計(jì)的目的是通過采集北京市二手房源數(shù)據(jù),進(jìn)行數(shù)據(jù)清洗、數(shù)據(jù)
分析和數(shù)據(jù)可視化,以獲取二手房市場(chǎng)的實(shí)際情況和趨勢(shì),并為購(gòu)房者提供決
策支持。在本畢業(yè)設(shè)計(jì)中,將使用requests、pandas、pyecharts和json等技
術(shù),同時(shí)還要克服反爬蟲措施,確保數(shù)據(jù)的可靠性和準(zhǔn)確性。最終的目標(biāo)是建
立一個(gè)完整的二手房市場(chǎng)數(shù)據(jù)分析平臺(tái),為購(gòu)房者提供全面的市場(chǎng)信息,幫助
他們做出明智的購(gòu)房決策。
1.2開發(fā)環(huán)境與工具
1.2.1Python簡(jiǎn)介
Python是一種簡(jiǎn)單易學(xué)、功能強(qiáng)大的編程語言,廣泛應(yīng)用于數(shù)據(jù)處理、人
工智能、Web開發(fā)等領(lǐng)域。Python具有清晰簡(jiǎn)潔的語法結(jié)構(gòu),使得編寫代碼變
得更加高效和愉悅。它擁有大量?jī)?yōu)秀的第三方庫(kù)和工具,如numpy、pandas、
matplotlib等,可以方便地處理各種數(shù)據(jù)分析、可視化等任務(wù)。同時(shí),Python
社區(qū)非?;钴S,各種問題可以很容易地找到解決方案和支持。Python語言已經(jīng)
成為許多人的首選編程語言,尤其是在數(shù)據(jù)科學(xué)和人工智能領(lǐng)域。
1.2.2Pandas簡(jiǎn)介
Pandas是一種開源的Python數(shù)據(jù)處理庫(kù),它是基于NumPy的擴(kuò)展庫(kù),可
以用來處理各種數(shù)據(jù)格式,如CSV、Excel、SQL、JSON等。它提供了DataFrame
和Series這兩個(gè)主要的數(shù)據(jù)結(jié)構(gòu),可以靈活地進(jìn)行數(shù)據(jù)清洗、預(yù)處理、轉(zhuǎn)換、
分析等操作。Pandas非常適合數(shù)據(jù)科學(xué)領(lǐng)域的工作,包括數(shù)據(jù)清洗和數(shù)據(jù)可視
化等任務(wù)。它的操作方式簡(jiǎn)單易學(xué),是數(shù)據(jù)分析和機(jī)器學(xué)習(xí)的必備工具之一。
1
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
1.2.3Pyecharts簡(jiǎn)介
Pyecharts是一款基于Python語言的數(shù)據(jù)可視化庫(kù),它能夠幫助用戶通過
簡(jiǎn)單的代碼實(shí)現(xiàn)各種圖表的繪制。該庫(kù)內(nèi)置了多種類型的圖表,包括折線圖、
柱狀圖、散點(diǎn)圖、餅圖等,并且支持對(duì)圖表的樣式、主題、數(shù)據(jù)等進(jìn)行靈活的
定制。使用Pyecharts可以快速生成美觀、直觀的數(shù)據(jù)可視化圖表,是Python
數(shù)據(jù)分析領(lǐng)域不可或缺的工具之一。
2需求分析
2.1可行性需求分析
1)技術(shù)可行性分析:
數(shù)據(jù)采集和分析是Python語言的優(yōu)勢(shì)之一,利用Python的requests庫(kù)和
BeautifulSoup庫(kù)可以輕松地從網(wǎng)頁(yè)中爬取所需信息,使用Pandas庫(kù)可以方便
地處理數(shù)據(jù)。此外,使用pyecharts庫(kù)可以將數(shù)據(jù)可視化展示,為后續(xù)分析提
供便利。
2)經(jīng)濟(jì)可行性分析:
房地產(chǎn)市場(chǎng)是一個(gè)龐大的市場(chǎng),其信息變化十分迅速,對(duì)于中介機(jī)構(gòu)和房
產(chǎn)公司而言,獲取市場(chǎng)信息非常重要。通過本項(xiàng)目,可以快速地獲取北京地區(qū)
的二手房源數(shù)據(jù),并對(duì)數(shù)據(jù)進(jìn)行分析,提高市場(chǎng)分析的效率和準(zhǔn)確性,降低信
息收集的成本。因此,本項(xiàng)目具有較高的經(jīng)濟(jì)可行性。
2.2采集目標(biāo)功能分析
通過網(wǎng)絡(luò)爬蟲技術(shù)獲取二手房源的相關(guān)信息,包括房源名稱、位置、面積、
價(jià)格、房型、樓層、朝向等。將采集的數(shù)據(jù)存儲(chǔ)到j(luò)son文件中,方便后續(xù)的數(shù)
據(jù)處理和分析。對(duì)清洗后的數(shù)據(jù)進(jìn)行分析,探索二手房源市場(chǎng)的價(jià)格走勢(shì)、房
源分布情況、不同地區(qū)房?jī)r(jià)等信息。
2.3關(guān)鍵技術(shù)分析
2.3.1網(wǎng)絡(luò)爬蟲技術(shù)
網(wǎng)絡(luò)爬蟲是一種自動(dòng)化程序,通過模擬用戶訪問行為,自動(dòng)訪問互聯(lián)網(wǎng)上
的網(wǎng)站,并獲取網(wǎng)站的數(shù)據(jù)。爬蟲通常會(huì)遵守網(wǎng)站的協(xié)議和規(guī)則,如robots.txt
2
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
文件,避免對(duì)目標(biāo)網(wǎng)站造成過大的負(fù)擔(dān)或損害。爬蟲技術(shù)可以廣泛應(yīng)用于數(shù)據(jù)
采集、信息分析、搜索引擎、機(jī)器學(xué)習(xí)等領(lǐng)域。
2.3.2文件存取技術(shù)
JSON是一種輕量級(jí)的數(shù)據(jù)交換格式,易于閱讀和編寫,同時(shí)也易于機(jī)器解
析和生成。它基于JavaScript語法,但可用于多種編程語言。JSON數(shù)據(jù)結(jié)構(gòu)
包含鍵值對(duì),可以表示數(shù)字、字符串、布爾值、數(shù)組和對(duì)象等數(shù)據(jù)類型。在Web
開發(fā)中,JSON常用于前后端數(shù)據(jù)傳輸和API接口的設(shè)計(jì)。
2.3.3可視化技術(shù)
可視化技術(shù)是一種將數(shù)據(jù)轉(zhuǎn)化為圖形化界面以便更直觀地展示數(shù)據(jù)的技
術(shù)。它可以幫助人們更好地理解數(shù)據(jù),從而更好地做出決策??梢暬夹g(shù)可以
使用各種圖形圖表,例如柱狀圖、折線圖、散點(diǎn)圖等等,同時(shí)還可以使用各種
顏色、標(biāo)簽和交互方式來使數(shù)據(jù)更加生動(dòng)和易于理解。常用的可視化工具包括
matplotlib、pyecharts、plotly等等。
3數(shù)據(jù)采集
3.1采集頁(yè)面分析
通過瀏覽器打開鏈家網(wǎng)官網(wǎng)/ershoufang/,該網(wǎng)
站可以查詢到北京全境的二手房信息,每頁(yè)顯示30條房源信息,選擇欄中可以
篩選北京某個(gè)區(qū)的二手房源。鏈家網(wǎng)首頁(yè)如下圖3-1所示:
圖3-1鏈家網(wǎng)首頁(yè)
3
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
本次數(shù)據(jù)采集的字段有房源名稱、房源所在區(qū)、地址、戶型、朝向、樓層、
建造年份、關(guān)注人數(shù)、發(fā)布時(shí)間、總價(jià)、每平米價(jià)格等。如下圖3-2所示:
圖3-2房源各個(gè)字段
其中“房源所在區(qū)“字段沒有直接顯示在房源標(biāo)簽html文檔中,需要通過
區(qū)域篩選欄選擇不同的區(qū),在對(duì)各個(gè)區(qū)域發(fā)起請(qǐng)求時(shí)保存“房源所在區(qū)”字段。
每個(gè)區(qū)的名稱和url保存在html中,如下圖3-3所示:
圖3-3北京各個(gè)區(qū)的名稱和url
在篩選欄中選擇“東城”并確認(rèn),頁(yè)面返回了東城所有的二手房源信息和
總套數(shù),根據(jù)二手房源總套數(shù)和每頁(yè)只顯示30條記錄的策略可以確定總頁(yè)數(shù),
從而制定頁(yè)面翻頁(yè)邏輯。如下圖3-4所示:
圖3-4每個(gè)區(qū)域二手房總套數(shù)
根據(jù)上述采集頁(yè)面的分析,現(xiàn)在已經(jīng)基本確定了頁(yè)面采集的方式和流程,
首先對(duì)首頁(yè)發(fā)起get請(qǐng)求,從響應(yīng)中解析出北京每個(gè)區(qū)的名稱和url,并逐個(gè)
對(duì)各個(gè)區(qū)進(jìn)行處理,在處理時(shí)保存各個(gè)區(qū)的名稱;根據(jù)每個(gè)區(qū)的二手房源總套
數(shù)計(jì)算總頁(yè)數(shù),進(jìn)而進(jìn)行翻頁(yè)處理。
3.2反爬策略分析
對(duì)網(wǎng)站進(jìn)行初步分析發(fā)現(xiàn),該網(wǎng)站的數(shù)據(jù)量比較大,如果在爬蟲程序中沒
有制定合理的反爬策略就很難全量采集到二手房源數(shù)據(jù)。Ip封禁是大多數(shù)網(wǎng)站
常用并且有效的反爬策略,如果同一個(gè)ip在短時(shí)間內(nèi)對(duì)網(wǎng)站發(fā)起了大量的請(qǐng)
4
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
求,該網(wǎng)站就會(huì)認(rèn)為這是爬蟲程序,從而封禁此ip。通過大量的測(cè)試發(fā)現(xiàn)該網(wǎng)
站存在封ip的情況,大量請(qǐng)求之后網(wǎng)站會(huì)彈出人機(jī)驗(yàn)證頁(yè),如下圖3-5所示:
圖3-5人機(jī)認(rèn)證頁(yè)
出現(xiàn)這種情況需要立馬更換ip才能繼續(xù)發(fā)起請(qǐng)求。本項(xiàng)目使用ip代理更
換ip,首先需要到快代理網(wǎng)站申請(qǐng)一個(gè)代理api鏈接,對(duì)這個(gè)代理api每發(fā)起
一次請(qǐng)求就會(huì)返回一個(gè)新的ip地址,然后在使用這個(gè)ip地址即可。如下圖3-6
所示:
圖3-6申請(qǐng)代理api鏈接
在爬蟲程序中在對(duì)目標(biāo)url發(fā)起請(qǐng)求時(shí)就不能直接使用requests.get方法
了。需要封裝一個(gè)change_ip_request方法,該方法首先對(duì)目標(biāo)url發(fā)起請(qǐng)求,
判斷響應(yīng)內(nèi)容,如果響應(yīng)內(nèi)容中包含了”人機(jī)驗(yàn)證”就使用代理api更換ip地
址重新對(duì)目標(biāo)url發(fā)起請(qǐng)求,該方法的返回response對(duì)象,以供后續(xù)方法調(diào)用
和解析response。change_ip_request方法如下所示:
5
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
#如果ip被封,則更換新ip繼續(xù)請(qǐng)求
defchange_ip_request(self,url):
headers={'User-Agent':random.choice(self.USER_AGENTS)}
response=requests.get(url,headers=headers,verify=True)
if"人機(jī)認(rèn)證"inresponse.text:
#使用ip代理
ip=
requests.get('/api/getdps/?secret_id=ovczrvb9z9lhk3oayy5j&num=1&signat
ure=omshi1knto9n2i40rsk47gq9ps&pt=1&sep=1')
proxies={'http':'http://'+ip.text}
print("更換ip地址"+str(ip.text)+"")
response=requests.get(url,headers=headers,proxies=proxies,verify=True)
print(response.text)
returnresponse
通過大量測(cè)試發(fā)現(xiàn),僅僅只更換ip地址是不能突破網(wǎng)站限制的,還需要隨
機(jī)更換請(qǐng)求頭。在爬蟲代碼中構(gòu)建了一個(gè)請(qǐng)求頭列表池,在使用requests發(fā)起
請(qǐng)求隨機(jī)到池中選址一個(gè)請(qǐng)求頭,這樣才能保證爬蟲能夠正常運(yùn)行。請(qǐng)求頭列
表池如下所示:
def__init__(self):
self.USER_AGENTS=[
"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,
likeGecko)Chrome/58.0.3029.110Safari/537.36Edge/16.16299",
"Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,like
Gecko)Chrome/50.0.2661.102Safari/537.36",
"Mozilla/5.0(WindowsNT6.1;WOW64;rv:54.0)Gecko/20100101Firefox/54.0",
"Mozilla/5.0(Macintosh;IntelMacOSX10_12_6)AppleWebKit/537.36
(KHTML,likeGecko)Chrome/61.0.3163.100Safari/537.36",
"Mozilla/5.0(Macintosh;IntelMacOSX10_12_6)AppleWebKit/604.1.38
(KHTML,likeGecko)Version/11.0Safari/604.1.38",
"Mozilla/5.0(X11;Ubuntu;Linuxx86_64;rv:55.0)Gecko/20100101
Firefox/55.0",
"Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,like
Gecko)Chrome/61.0.3163.79Safari/537.36"]
3.3多線程實(shí)現(xiàn)
為了提高數(shù)據(jù)采集的效率,在程序中使用了多線程。Python多線程是指在
一個(gè)Python進(jìn)程中同時(shí)運(yùn)行多個(gè)線程,每個(gè)線程執(zhí)行不同的任務(wù),以達(dá)到并發(fā)
執(zhí)行的效果。在Python中可以通過使用threading模塊來創(chuàng)建多線程。該模
塊提供了一個(gè)Thread類,可以通過創(chuàng)建該類的實(shí)例來創(chuàng)建線程。
6
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
在開啟多線程之前需要拿到北京各個(gè)區(qū)的url鏈接,而后對(duì)每個(gè)區(qū)開啟一
個(gè)線程。使用get_area_items方法獲取每個(gè)區(qū)的名稱url鏈接。詳細(xì)代碼如下
所示:
defget_area_items(self,start_url):
response=self.change_ip_request(start_url)
html=etree.HTML(response.text)
area_items=html.xpath('/html/body/div[3]/div/div[1]/dl[2]/dd/div[1]/div/a')
method=lambdax:{'area':x.xpath('./text()')[0],'url':''+
x.xpath('./@href')[0]}
area_items_dic=list(map(method,area_items))
print(area_items_dic)
self.request_area(area_items_dic)
首先使用xpath方法獲取到每個(gè)區(qū)所在的a標(biāo)簽列表,在使用map方法和
lambda表達(dá)式處理a標(biāo)簽,將區(qū)名稱和區(qū)url以字段的方式保存到列表中,最
后調(diào)用request_area方法以多線程的方法分別對(duì)各個(gè)區(qū)進(jìn)行處理。多線程處理
方法如下所示:
defrequest_area(self,area_items_dic):
Thread=[]
forarea_iteminarea_items_dic:
area=area_item['area']
url=area_item['url']
#創(chuàng)建線程
t1=threading.Thread(target=self.next_page,args=(url,area,1,))
Thread.append(t1)
#開啟所有線程
fortinThread:
t.start()
#等待結(jié)束所有線程
fortinThread:
t.join()
具體來說,該函數(shù)接受一個(gè)包含地區(qū)和對(duì)應(yīng)鏈接的字典列表
area_items_dic,遍歷列表中每個(gè)字典元素,獲取地區(qū)和鏈接,并為每個(gè)地區(qū)
創(chuàng)建一個(gè)線程進(jìn)行爬取。在循環(huán)中,使用threading.Thread()方法創(chuàng)建一個(gè)
線程對(duì)象t1,并將self.next_page()方法作為目標(biāo)函數(shù)傳入,同時(shí)也將url、
area和1作為參數(shù)傳入。這個(gè)1是當(dāng)前的頁(yè)數(shù),該參數(shù)可以方便后續(xù)翻頁(yè)的
處理。接著將線程對(duì)象t1添加到Thread列表中。這樣,每次循環(huán)都會(huì)創(chuàng)建
一個(gè)線程,并將其添加到列表中。
7
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
在循環(huán)結(jié)束后,使用for循環(huán)遍歷Thread列表,對(duì)其中的每個(gè)線程對(duì)象
調(diào)用start()方法,以開啟所有線程,使它們并發(fā)執(zhí)行。接著,再次使用for
循環(huán)遍歷Thread列表,并對(duì)其中的每個(gè)線程對(duì)象調(diào)用join()方法,以等待
所有線程執(zhí)行完畢,確保所有線程的爬取任務(wù)都已經(jīng)完成。
3.4翻頁(yè)實(shí)現(xiàn)
函數(shù)next_page(),它實(shí)現(xiàn)了在鏈家網(wǎng)站中爬取指定區(qū)域的房產(chǎn)數(shù)據(jù),并
實(shí)現(xiàn)了翻頁(yè)功能。具體來說,該函數(shù)接收三個(gè)參數(shù):url、area和page,其中
url表示該區(qū)域的鏈接,area表示該區(qū)域的名稱,page表示當(dāng)前爬取的頁(yè)數(shù)。
詳細(xì)代碼如下所示:
defnext_page(self,url,area,page):
response=self.change_ip_request(url+'/pg'+str(page))
print(response.url)
html=etree.HTML(response.text)
max_page_num=
int(''.join(html.xpath('//*[@id="content"]/div[1]/div[2]/h2/span/text()')))/30
self.get_house_detail(response,area)
ifpage<=max_page_num+1:
print("======正在采集"+area+"的數(shù)據(jù),第"+str(page)+"頁(yè)
======")
page+=1
self.next_page(url,area,page)
該函數(shù)首先通過self.change_ip_request()方法發(fā)送請(qǐng)求,并使用
etree.HTML()方法解析HTML頁(yè)面。接著,通過XPath表達(dá)式獲取該區(qū)域的
最大頁(yè)數(shù)max_page_num,并使用self.get_house_detail()方法對(duì)該頁(yè)的房
產(chǎn)數(shù)據(jù)進(jìn)行采集。如果當(dāng)前頁(yè)數(shù)page小于等于最大頁(yè)數(shù)max_page_num+1,
則將page加1,然后遞歸調(diào)用next_page()方法,以繼續(xù)爬取該區(qū)域的下一
頁(yè)數(shù)據(jù)。
需要注意的是,由于遞歸調(diào)用會(huì)導(dǎo)致函數(shù)的棧幀不斷增加,因此在爬取大
量數(shù)據(jù)時(shí),可能會(huì)出現(xiàn)棧溢出的情況。為了避免這種情況的發(fā)生,可以考慮使
用非遞歸的方式實(shí)現(xiàn)翻頁(yè)功能,或者使用尾遞歸優(yōu)化等技術(shù)來減少函數(shù)調(diào)用的
棧幀使用。此外,在爬取數(shù)據(jù)時(shí),還需要注意處理可能出現(xiàn)的異常情況,例如
網(wǎng)絡(luò)連接失敗、HTML頁(yè)面解析失敗等情況。
8
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
3.5解析房源信息
使用get_house_detail()方法解析鏈家網(wǎng)的二手房源數(shù)據(jù),并將數(shù)據(jù)保存
到文件中。具體來說,該函數(shù)接收兩個(gè)參數(shù):response和area,其中response
表示從鏈家網(wǎng)站中獲取到的HTTP響應(yīng)對(duì)象,area表示該區(qū)域的名稱。詳細(xì)代
碼如下所示:
defget_house_detail(self,response,area):
html=etree.HTML(response.text)
house_items=html.xpath('//*[@id="content"]/div[1]/ul/li')
result={}
forhouse_iteminhouse_items:
house_name=house_item.xpath('./div[1]/div[1]/a/text()')
address1=house_item.xpath('./div[1]/div[2]/div/a[1]/text()')
address2=house_item.xpath('./div[1]/div[2]/div/a[2]/text()')
house_info=house_item.xpath('./div/div[3]/div/text()')
follow_info=house_item.xpath('./div/div[4]/text()')
price_all=house_item.xpath('.//div[@class="priceInfo"]/div/span/text()')
price_unit=house_item.xpath('.//div[@class="priceInfo"]/div[2]/span/text()')
result['house_name']=''.join(house_name)
result['area']=area
result['address1']=''.join(address1)
result['address2']=''.join(address2)
result['house_info']=''.join(house_info)
result['follow_info']=''.join(follow_info)
result['price_all']=''.join(price_all)
result['price_unit']=''.join(price_unit)
print(result)
self.saveData(result)
該函數(shù)首先使用etree.HTML()方法解析HTML頁(yè)面,并使用XPath表達(dá)
式獲取到該頁(yè)面中所有的房產(chǎn)數(shù)據(jù)。然后,使用循環(huán)遍歷每一個(gè)房產(chǎn)數(shù)據(jù),通
過XPath表達(dá)式獲取該房產(chǎn)的各個(gè)屬性,例如房屋名稱、地址、房屋信息、關(guān)
注信息、總價(jià)和單價(jià)等。接著,將這些屬性組成一個(gè)字典result,并打印輸出
該字典,以方便調(diào)試和查看數(shù)據(jù)。最后,將該字典保存到文件中,通過
self.saveData()方法實(shí)現(xiàn)。
需要注意的是,由于鏈家網(wǎng)站的HTML頁(yè)面結(jié)構(gòu)可能會(huì)發(fā)生變化,因此需
要定期更新XPath表達(dá)式,以保證程序能夠正確地獲取房產(chǎn)數(shù)據(jù)。此外,在爬
取數(shù)據(jù)時(shí),還需要注意處理可能出現(xiàn)的異常情況,例如XPath解析失敗、字典
9
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
保存失敗等情況。
3.6保存到j(luò)son文件
將獲取到的數(shù)據(jù)使用saveData方法保存到j(luò)son文件中。具體來說,該函
數(shù)接收一個(gè)參數(shù)result,該參數(shù)表示獲取到的單個(gè)房產(chǎn)數(shù)據(jù),是一個(gè)Python
字典類型。詳細(xì)代碼如下所示:
defsaveData(self,result):
json_str=json.dumps(result,ensure_ascii=False)
withopen("house.json","a",encoding="utf-8")asf:
f.write(json_str+"\n")
該函數(shù)首先使用json.dumps()方法將該字典轉(zhuǎn)換成JSON字符串,設(shè)置
ensure_ascii=False參數(shù)可以保證輸出的JSON中文字符不會(huì)被轉(zhuǎn)義。然后,
使用withopen()語句打開文件house.json,將JSON字符串寫入文件中。
由于爬取到的數(shù)據(jù)可能很大,因此使用追加模式"a",每次將數(shù)據(jù)添加到文件
的末尾,而不是覆蓋之前的數(shù)據(jù)。需要注意的是,在保存數(shù)據(jù)時(shí),還需要考慮
異常處理和線程安全的問題。例如,當(dāng)寫入文件時(shí)出現(xiàn)異常,需要進(jìn)行錯(cuò)誤處
理,以避免程序崩潰。此外,由于多個(gè)線程可能會(huì)同時(shí)訪問同一個(gè)文件,因此
需要確保寫入文件時(shí)的線程安全性,可以使用鎖機(jī)制或者將寫入文件的操作放
在同步塊中,以保證每次只有一個(gè)線程能夠?qū)懭胛募?/p>
3.7運(yùn)行爬蟲程序
使用run方法啟動(dòng)爬蟲,將url傳入給get_area_items方法。詳細(xì)代碼如
下所示:
defrun(self,start_url):
self.get_area_items(start_url)
Main方法如下所示:
if__name__=='__main__':
spider=Spider()
spider.run('/ershoufang/')
程序運(yùn)行日志如下圖3-7所示:
10
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
圖3-7程序運(yùn)行日志
程序運(yùn)行結(jié)束之后會(huì)在當(dāng)前路徑下生成house.json文件,打開文件可以發(fā)
現(xiàn)已經(jīng)采集了2萬4千多條記錄,已經(jīng)滿足了數(shù)據(jù)分析與可視化的要求。如下
圖3-8所示:
圖3-8house.json文件
本項(xiàng)目json作為數(shù)據(jù)傳輸和處理格式,具有以下優(yōu)點(diǎn):易于解析:JSON是
一種基于文本的格式,易于解析和處理。Python中可以使用json模塊解析和
生成JSON格式數(shù)據(jù),操作簡(jiǎn)單;結(jié)構(gòu)化:JSON格式可以表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu);
可讀性好:JSON數(shù)據(jù)的格式結(jié)構(gòu)非常清晰,易于閱讀和理解;支持多種編程語
言:由于JSON是一種開放的數(shù)據(jù)格式,支持多種編程語言。因此,JSON數(shù)據(jù)
可以輕松地在不同的系統(tǒng)之間進(jìn)行交換和共享,實(shí)現(xiàn)數(shù)據(jù)的互通性。
4數(shù)據(jù)清洗與處理
數(shù)據(jù)清洗是數(shù)據(jù)預(yù)處理中重要的步驟之一,它是指對(duì)原始數(shù)據(jù)進(jìn)行篩選、
整理、轉(zhuǎn)換、填充等一系列操作,以達(dá)到消除數(shù)據(jù)噪聲、提高數(shù)據(jù)質(zhì)量、減少
數(shù)據(jù)冗余、適應(yīng)數(shù)據(jù)分析模型等目的的過程。數(shù)據(jù)清洗可以使得數(shù)據(jù)更加規(guī)整,
更符合數(shù)據(jù)分析模型的要求,有利于進(jìn)行數(shù)據(jù)挖掘等任務(wù),從而挖掘出更多有
價(jià)值的信息。綜上所述,數(shù)據(jù)清洗是數(shù)據(jù)預(yù)處理中至關(guān)重要的一個(gè)環(huán)節(jié),可以
提高數(shù)據(jù)質(zhì)量、減少冗余、適應(yīng)分析模型等,從而幫助我們更好地挖掘數(shù)據(jù)背
后的價(jià)值。本項(xiàng)目數(shù)據(jù)清洗使用Python中的numpy和pandas庫(kù)進(jìn)行處理。
11
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
4.1數(shù)據(jù)清洗需求
1)使用pandas庫(kù)的read_json()函數(shù)讀取house.json文件
2)從house_info字段中解析出戶型、面積、朝向、裝修風(fēng)格、樓層、建造年
份、建筑結(jié)構(gòu)。將樓層拆分成兩個(gè)字段樓層和具有樓層,如“低樓層(共11
層)“處理后為兩個(gè)字段”低樓層“和”11“。剔除建造年份字段中多余
的字符串,如“1991年建“處理后”1991“,如果house_info字段中沒有
建造年份則用“0000“代替。
3)從follow_info字段中解析出關(guān)注人數(shù)、發(fā)布天數(shù),剔除其中多余的字符
串,比如“1人關(guān)注”處理后“1”。然后根據(jù)發(fā)布天數(shù)計(jì)算出發(fā)布日期。
4)由于price_all字段是房屋的總價(jià),而該字段的單位是“元/平”,明顯單
位存在問題,所以將“元/平”替換成“萬”。
4.2數(shù)據(jù)讀取與處理
創(chuàng)建check_json_file,用于讀取一個(gè)JSON文件,并檢查文件中每個(gè)JSON
對(duì)象的格式。函數(shù)的作用是讀取JSON文件中的數(shù)據(jù),并將格式正確的數(shù)據(jù)轉(zhuǎn)換
為DataFrame格式。在讀取JSON文件的過程中,函數(shù)會(huì)跳過格式不正確的數(shù)據(jù)。
如果某個(gè)JSON對(duì)象的格式正確,那么該對(duì)象將被添加到一個(gè)列表中,并最終轉(zhuǎn)
換為DataFrame格式返回。
defcheck_json_file(input_file):
#用于存儲(chǔ)格式正確的json數(shù)據(jù)
json_data_list=[]
#打開輸入文件
withopen(input_file,'r',encoding='utf-8')asf:
forlineinf:
try:
#將每一行json數(shù)據(jù)轉(zhuǎn)換成python對(duì)象
json_data=json.loads(line.strip())
if'年建'notinjson_data['house_info']:
house_info_li=str(json_data['house_info']).split('|')
structure=house_info_li[-1]
house_info_pre=house_info_li[:-1]
12
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
house_info_pre.append("0000年建")
house_info_pre.append(structure)
json_data['house_info']='|'.join(house_info_pre)
#檢查json數(shù)據(jù)格式是否正確
if'house_name'injson_dataand'area'injson_dataand'address1'injson_data
and'address2'injson_dataand'house_info'injson_dataand'follow_info'injson_dataand
'price_all'injson_dataand'price_unit'injson_data:
#將格式正確的json數(shù)據(jù)添加到列表中
json_data_list.append(json_data)
except:
#如果轉(zhuǎn)換失敗或者格式不正確則跳過該行數(shù)據(jù)
pass
#將列表中的json數(shù)據(jù)轉(zhuǎn)換成DataFrame格式
df=pd.DataFrame(json_data_list)
returndf
該函數(shù)還有一個(gè)重要功能,就是處理house_info中的房屋建造年份字段。
House_info字段有兩種格式,第一種包含了房屋建造年份字段,而第二種沒有
包含,在后續(xù)使用pandas清洗數(shù)據(jù)時(shí),這兩種情況需要編寫兩個(gè)不同的正則表
達(dá)式,這兩個(gè)正則表達(dá)式不能同時(shí)被應(yīng)用,用其他方式處理也及其復(fù)雜。所有
在讀取house.json文件時(shí)就將house_info字段的長(zhǎng)度統(tǒng)一。
統(tǒng)一house_info字段長(zhǎng)度的具體邏輯如下:首先檢查JSON對(duì)象中名為
"house_info"的字符串是否包含"年建"這個(gè)子字符串。如果不包含,代碼將使
用"|"字符作為分隔符,將"house_info"字段拆分為一個(gè)列表。然后,代碼將獲
取列表中的最后一個(gè)元素,并將其賦值給變量"structure"。接下來,代碼將創(chuàng)
建一個(gè)新的"house_info_pre"列表,該列表包含原始列表中除了最后一個(gè)元素
之外的所有元素,并在末尾添加了一個(gè)字符串"0000年建",然后將
"structure"變量添加到列表的末尾。最后,代碼將使用"|"字符將新的
"house_info_pre"列表合并成一個(gè)字符串,并將其賦值回JSON對(duì)象的
"house_info"字段。
4.3數(shù)據(jù)清洗
本項(xiàng)目數(shù)據(jù)清洗主要使用pandas來完成。Pandas是一個(gè)開源的Python數(shù)
13
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
據(jù)分析庫(kù),提供了靈活高效的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)分析工具,非常適合進(jìn)行數(shù)據(jù)清
洗和預(yù)處理。
創(chuàng)建data_clean方法并傳入Dataframe對(duì)象,讀取Dataframe的house_info
列,從其中解析出戶型、面積、朝向、裝修風(fēng)格、樓層、建造年份、建筑結(jié)構(gòu)
字段,編寫正則表達(dá)式并使用str.extract()函數(shù)從字符串列中提取特定的信
息。詳細(xì)代碼如下所示:
str_contain_year='(\d+室\d+廳)\|([\d.]+)平米\|(.+)\|([^]+)\|(.+)\|(\d+)年建\|(.+)'
li_contain_year=['type','size','direction','decoration','floor','year','structure']
df[li_contain_year]=df['house_info'].str.extract(str_contain_year)
df=df.drop('house_info',axis=1)
將樓層字段拆分成兩個(gè)字段:floor_level和floor_all,并刪除原有的樓
層字段;清洗"year"字段中的冗余字符串"年建";從follow_info字段中解析
出關(guān)注人數(shù)、發(fā)布天數(shù)。詳細(xì)代碼如下所示:
#將樓層拆分成兩個(gè)字段樓層和具有樓層
df[['floor_level','floor_all']]=df['floor'].str.extract('(.+)\(共(\d+)層\)')
df=df.drop('floor',axis=1)
#剔除建造年份字段中多余的字符串
df['year']=df['year'].apply(lambdax:re.sub(r'年建','',x)iftype(x)==strelse'0000')
#從follow_info字段中解析出關(guān)注人數(shù)、發(fā)布天數(shù)
df[['follow_num','post_time']]=df['follow_info'].str.extract('(\d+)人關(guān)注/([^]+)發(fā)布')
df=df.drop('follow_info',axis=1)
根據(jù)發(fā)布天數(shù)計(jì)算出發(fā)布日期;將price_all字段的單位由“元/平”替換
成“萬”。最后將清洗后的數(shù)據(jù)保存到j(luò)son文件中。詳細(xì)代碼如下所示:
#根據(jù)發(fā)布天數(shù)計(jì)算出發(fā)布日期
df['post_date']=df['post_time'].apply(calculate_date)
#將price_all字段的單位由“元/平”替換成“萬”
df['price_all']=df['price_all'].str.replace('元/平','萬')
df['price_unit']=df['price_unit'].str.replace('元/平','元')
#將清洗后的數(shù)據(jù)保存為house_clean.json
df.to_json('house_clean.json',orient='records',lines=True,force_ascii=False)
14
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
4.4數(shù)據(jù)清洗結(jié)果
運(yùn)行check_json_file方法和data_clean方法進(jìn)行數(shù)據(jù)清洗。代碼如下所
示:
df=check_json_file('house.json')
data_clean(df)
程序運(yùn)行結(jié)束之后會(huì)到本地創(chuàng)建一個(gè)house_clean.json文件,其文件內(nèi)容
如下圖所示:
圖4-1數(shù)據(jù)清洗結(jié)果
從數(shù)據(jù)清洗結(jié)果文件中可以看到house_info字段和floor字段被正確解析
了。后續(xù)通過pandas讀取該文件即可進(jìn)行數(shù)據(jù)的統(tǒng)計(jì)與分析。
5數(shù)據(jù)統(tǒng)計(jì)與分析
5.1數(shù)據(jù)分析說明
數(shù)據(jù)分析使用pandas來完成,Pandas是一個(gè)Python數(shù)據(jù)處理庫(kù),它提供
了高性能、易于使用的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)分析工具,能夠輕松處理各種數(shù)據(jù)類型
和來源,是Python生態(tài)系統(tǒng)中的一個(gè)重要組成部分。Pandas提供了一系列數(shù)
據(jù)分析函數(shù),可以幫助用戶對(duì)數(shù)據(jù)進(jìn)行統(tǒng)計(jì)分析、聚合操作等。比如,用戶可
以使用groupby()函數(shù)對(duì)數(shù)據(jù)進(jìn)行分組操作;使用describe()函數(shù)對(duì)數(shù)據(jù)進(jìn)行
基本統(tǒng)計(jì)分析;使用apply()函數(shù)對(duì)數(shù)據(jù)進(jìn)行自定義操作等。
5.2數(shù)據(jù)展示
5.2.1統(tǒng)計(jì)各區(qū)的房源數(shù)量和平均價(jià)格
讀取一個(gè)名為"house_clean.json"的JSON文件,并將其中的房源數(shù)據(jù)
轉(zhuǎn)換為一個(gè)PandasDataFrame對(duì)象。對(duì)DataFrame進(jìn)行一些數(shù)據(jù)清洗操作,
15
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
如將'price_unit'字段中的單位“元”去除,并將其中的逗號(hào)替換為小數(shù)點(diǎn)。
對(duì)'area'字段進(jìn)行分組統(tǒng)計(jì),得到每個(gè)區(qū)域的房源數(shù)量和平均單價(jià)。使用
pyecharts庫(kù)中的Map類創(chuàng)建一個(gè)地圖對(duì)象,將房源數(shù)量和平均單價(jià)數(shù)據(jù)分別
添加到地圖上。設(shè)置地圖的全局選項(xiàng),如標(biāo)題、視覺映射選項(xiàng)等。最后將地圖
保存為一個(gè)HTML文件。詳細(xì)代碼如下所示:
importjson,re
importpandasaspd
frompyecharts.chartsimportMap
frompyechartsimportoptionsasopts
#讀取JSON文件
withopen('house_clean.json','r',encoding='gbk')asf:
houses=[json.loads(line)forlineinf.readlines()]
#轉(zhuǎn)換為DataFrame
df=pd.DataFrame(houses)
df['price_unit']=df['price_unit'].map(lambdax:float(str(x).replace('元','').replace(',','.')))
#根據(jù)area字段分組統(tǒng)計(jì)house_name的數(shù)量和price_unit的平均價(jià)格
result=df.groupby('area').agg({'house_name':'count','price_unit':'mean'}).reset_index()
result.columns=['area','count','mean_price_unit']
result['mean_price_unit']=result['mean_price_unit'].map(lambdax:round(x))
result['area']=result['area'].map(lambdax:str(x)+'區(qū)')
#繪制地圖
map=(
Map()
.add(
series_name='房源數(shù)量',
data_pair=[list(z)forzinzip(result['area'],result['count'])],
maptype='北京',
label_opts=opts.LabelOpts(is_show=True,font_size=10)
)
.add(
series_name='平均單價(jià)',
16
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
data_pair=list(zip(result['area'],result['mean_price_unit'])),
maptype='北京',
label_opts=opts.LabelOpts(is_show=False)
)
.set_global_opts(
title_opts=opts.TitleOpts(title='北京市房源分布'),
visualmap_opts=opts.VisualMapOpts(
max_=max(result['count']),
range_color=['#fff','#00BFFF','#00FA9A','#FFD700','#FF8C00','#FF0000'],
)))
#保存為HTML文件
map.render('beijing_map.html')
運(yùn)行結(jié)果如下圖所示:
圖5-1北京市地圖
北京市的房?jī)r(jià)整體上呈現(xiàn)區(qū)域性分布,從平均價(jià)格單位來看,東城區(qū)、西
城區(qū)和海淀區(qū)屬于高房?jī)r(jià)區(qū),分別為114、129和102萬元/平方米,且這些區(qū)
域的二手房數(shù)量相對(duì)較少,說明這些區(qū)域的房?jī)r(jià)相對(duì)較高且供給較為緊張。北
京市的中等房?jī)r(jià)區(qū)主要分布在豐臺(tái)區(qū)、石景山區(qū)和昌平區(qū),二手房的平均價(jià)格
17
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
分別為61、54和48萬元/平方米,且這些區(qū)域的二手房數(shù)量相對(duì)較多,說明這
些區(qū)域的房?jī)r(jià)相對(duì)較為平穩(wěn),供求相對(duì)平衡。北京市的低房?jī)r(jià)區(qū)主要分布在大
興區(qū)、通州區(qū)和懷柔區(qū),二手房的平均價(jià)格分別為44、44和30元/平方米,且
這些區(qū)域的二手房數(shù)量相對(duì)較多,說明這些區(qū)域的房?jī)r(jià)相對(duì)較低且供給相對(duì)充
足。綜上所述,北京市的房?jī)r(jià)整體呈現(xiàn)出明顯的區(qū)域性分布,不同區(qū)域的房?jī)r(jià)
和二手房數(shù)量有著明顯的差異,投資者在購(gòu)買房產(chǎn)時(shí)應(yīng)該綜合考慮各方面因素,
以選擇適合自己的房產(chǎn)投資方案。
5.2.2統(tǒng)計(jì)不同朝向與樓層的房源數(shù)量與價(jià)格
使用了pandas和pyecharts庫(kù)來讀取一個(gè)JSON文件并繪制柱狀圖。首先,
代碼使用pandas的read_json()方法讀取一個(gè)名為house_clean.json的JSON
文件,其中l(wèi)ines=True參數(shù)表示每一行都是一個(gè)JSON對(duì)象。然后,代碼使用
str.strip()方法剔除了direction字段中的空格,并使用map()方法將
price_unit字段中的字符串類型轉(zhuǎn)換為浮點(diǎn)型,去掉了單位和千位分隔符。
接下來,代碼使用groupby()方法將數(shù)據(jù)按照floor_level字段進(jìn)行分組,
然后使用agg()方法對(duì)每個(gè)組內(nèi)的數(shù)據(jù)進(jìn)行統(tǒng)計(jì),其中count表示數(shù)量,mean
表示平均值。最后,代碼使用reset_index()方法將分組后的數(shù)據(jù)重新設(shè)置索
引。接著,代碼使用pyecharts庫(kù)的Bar()類創(chuàng)建一個(gè)柱狀圖對(duì)象。使用
add_xaxis()方法添加x軸數(shù)據(jù),使用add_yaxis()方法添加y軸數(shù)據(jù),并使用
set_global_opts()方法設(shè)置全局參數(shù),例如標(biāo)題和x軸名稱。
importpandasaspd
frompyecharts.chartsimportBar
frompyechartsimportoptionsasopts
#讀取json文件
df=pd.read_json('house_clean.json',lines=True)
#剔除direction中的空格
df['direction']=df['direction'].str.strip()
df['price_unit']=df['price_unit'].map(lambdax:float(str(x).replace('元','').replace(',','.')))
#根據(jù)floor_level分組,求數(shù)量和price_unit平均價(jià)格
grouped=df.groupby('floor_level').agg({'house_name':'count','price_unit':
'mean'}).reset_index()
grouped['price_unit']=grouped['price_unit'].map(lambdax:round(x))
18
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
#繪制柱狀圖
bar_chart=(
Bar()
.add_xaxis(list(grouped['floor_level']))
.add_yaxis("數(shù)量",list(grouped['house_name']))
.add_yaxis("平均價(jià)格",list(round(grouped['price_unit'],2)))
.set_global_opts(
title_opts=opts.TitleOpts(title="按樓層分組統(tǒng)計(jì)"),
xaxis_opts=opts.AxisOpts(name="樓層"),
))
bar_chart.render('柱狀圖.html')
圖5-2柱狀圖
從平均價(jià)格單位來看,地下室的二手房平均價(jià)格最高,為68萬元/平方米,
其次是低樓層和頂層,分別為66和57萬元/平方米,這可能是因?yàn)榈叵率业姆?/p>
屋位置特殊,且擁有更好的采光條件;而低樓層和頂層則可能因?yàn)榇嬖谠胍簟?/p>
采光、通風(fēng)等方面的問題,導(dǎo)致其價(jià)格相對(duì)較低。從二手房數(shù)量來看,中樓層
的二手房數(shù)量最多,達(dá)到了6706套,其次是高樓層和低樓層,分別為3904和
3597套,這可能是因?yàn)橹袠菍拥奈恢孟鄬?duì)較為舒適,采光、通風(fēng)等方面的條件
較好??傮w來說,不同樓層的二手房?jī)r(jià)格和數(shù)量都有一定的差異,投資者在購(gòu)
買房產(chǎn)時(shí)應(yīng)該綜合考慮各方面因素,以選擇適合自己的樓層投資方案。
19
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
5.2.3統(tǒng)計(jì)各裝修風(fēng)格的數(shù)量
使用Pandas的read_json函數(shù)讀取一個(gè)名為"house_clean.json"的JSON
格式文件,并將其轉(zhuǎn)換為一個(gè)DataFrame對(duì)象df。對(duì)DataFrame中的
"price_unit"列進(jìn)行數(shù)據(jù)清洗,將其中的"元"字符剔除并將逗號(hào)替換為小數(shù)點(diǎn),
最終轉(zhuǎn)換為float類型。使用groupby函數(shù)對(duì)DataFrame對(duì)象df按照
"decoration"列進(jìn)行分組,統(tǒng)計(jì)每組中"house_name"的數(shù)量,并計(jì)算每組中
"price_unit"的平均值。使用Pyecharts中的Pie()函數(shù)創(chuàng)建一個(gè)餅圖對(duì)象,
通過add方法將數(shù)據(jù)添加到餅圖中,設(shè)置全局選項(xiàng)和系列選項(xiàng),最后使用render
方法將餅圖保存到名為"餅圖.html"的文件中。
importpandasaspd
frompyecharts.chartsimportPie
frompyechartsimportoptionsasopts
#讀取json文件
df=pd.read_json('house_clean.json',lines=True)
#剔除price_unit中的“元”字符并將逗號(hào)替換成.
df['price_unit']=df['price_unit'].str.replace('元','').str.replace(',','').astype(float)
#根據(jù)decoration分組,求數(shù)量和price_unit平均價(jià)格
grouped=df.groupby('decoration').agg({'house_name':'count'}).reset_index()
#繪制餅圖
pie_chart=(
Pie()
.add("數(shù)量",[list(z)forzinzip(grouped['decoration'],list(grouped['house_name']))])
.set_global_opts(
title_opts=opts.TitleOpts(title="按裝修程度分組統(tǒng)計(jì)",padding=10),
legend_opts=opts.LegendOpts(orient="vertical",
pos_left="left",padding=70,item_width=10,item_height=10)
).set_series_opts(label_opts=opts.LabelOpts(formatter=":{c}")))
pie_chart.render('餅圖.html')
20
湖南商務(wù)職業(yè)技術(shù)學(xué)院畢業(yè)設(shè)計(jì)
圖5-3餅圖
從數(shù)量來看,精裝二手房數(shù)量最多,達(dá)到了11505套,其次是簡(jiǎn)裝和其他,
分別為8844和3200套,而毛坯二手房數(shù)量最少,為761套。在當(dāng)前的房地產(chǎn)
市場(chǎng),二手房市場(chǎng)上,精裝房屋的銷售較為受歡迎,可能是因?yàn)榫b房屋已經(jīng)
在內(nèi)部裝修和裝飾方面花費(fèi)了大量的人力和物力,從而為購(gòu)房者提供了更好的
住宿體驗(yàn)。在購(gòu)買二手房時(shí),裝修風(fēng)格也是一個(gè)非常重要的因素,購(gòu)房者需要
根據(jù)自己的需求和喜好來選擇不同的裝修風(fēng)格,以滿足自己的住宿需求。
5.2.4統(tǒng)計(jì)每年建造的房屋數(shù)量與價(jià)格
使用pyecharts庫(kù),通過對(duì)讀取的數(shù)據(jù)進(jìn)行一些處理和統(tǒng)計(jì),繪制了一個(gè)
折線圖。具體地,代碼首先讀取了一個(gè)JSON文件house_clean.json,然后使
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年小型蒸發(fā)儀項(xiàng)目投資價(jià)值分析報(bào)告
- 二年級(jí)數(shù)學(xué)計(jì)算題專項(xiàng)練習(xí)1000題匯編
- 三年級(jí)數(shù)學(xué)計(jì)算題專項(xiàng)練習(xí)及答案
- 人力資源居間服務(wù)批文
- 倉(cāng)儲(chǔ)裝修項(xiàng)目終止協(xié)議
- 建筑行業(yè)軟件項(xiàng)目實(shí)施保障措施
- 南京財(cái)經(jīng)大學(xué)文獻(xiàn)綜述的未來發(fā)展趨勢(shì)
- 2024年度浙江省公共營(yíng)養(yǎng)師之四級(jí)營(yíng)養(yǎng)師真題練習(xí)試卷B卷附答案
- 外研版四年級(jí)下冊(cè)英語多元智能發(fā)展計(jì)劃
- 幼兒園體育活動(dòng)效果評(píng)估范文
- 銳途管理人員測(cè)評(píng)試題目的
- 焊接材料-DIN-8555-標(biāo)準(zhǔn)
- 工程索賠真實(shí)案例范本
- 重癥醫(yī)學(xué)科運(yùn)用PDCA循環(huán)降低ICU失禁性皮炎發(fā)生率品管圈QCC持續(xù)質(zhì)量改進(jìn)成果匯報(bào)
- 個(gè)人股權(quán)證明書
- 醫(yī)院運(yùn)送工作介紹
- 重癥患者的容量管理
- 學(xué)習(xí)游戲?qū)χ行W(xué)生學(xué)業(yè)成績(jī)的影響
- 小學(xué)四年級(jí)上冊(cè)遞等式計(jì)算100題及答案
- 新版?zhèn)€人簡(jiǎn)歷Excel表格模板共2聯(lián)
- (完整)中國(guó)象棋教案
評(píng)論
0/150
提交評(píng)論