python建筑案例_Python数据分析实战-链家北京二手房价分析
前言
最近在自學Python,通過學習大家的分享案例,看到使用Python進行較多的主要4個方面:爬蟲,數據處理,數據可視化以及機器學習建模。對我來說目標就是:
我將1-3歸為Phase1,也就是這篇文章的主體內容。本篇以模仿為主,俗話說輸出是最好的學習方式。希望通過這篇文章可以增加自己對Python基礎的熟練程度,內化常規的數據分析思路。
分析思路
分析目標:查看北京二手居民住房的分布價格情況Part 1- 數據讀取和預處理理解變量、數據選取、重復值缺失值處理Part 2 - 北京市房源分布
數量、單價、總價Part 3 - 各城區房源分布Part 4 - 各城區房價分布
單價分布、總價分布、高價Top15小區、低價Top15小區Part 5 - 各城區房源面積分布
全市平均面積分布、各城區平均面積分布、各城區總面積分布Part 6 - 房價與房源特性的關系
房價與戶型、樓層、朝向、建筑年代的關系
Part 1 - 數據讀取和預處理
本篇使用參考資料文章3的數據:https://pan.baidu.com/s/1_n3TkvESgOXfl5TUoqlk7w。
#導入常用包 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns#導入數據 filepath='./lianjia_beijing.csv' rawdata=pd.read_csv(filepath,header=0)#查看數據 rawdata.head()可以看到一共有12個變量,包括:
- Direction: 房屋朝向;
- Region/District/Gadern: 城區/街道/小區地址或者名稱
- Id: 鏈家編碼
- Elevator: 樓是否有電梯
- Floor:樓層
- Layout: 房屋戶型
- Renovation: 裝修情況
- Size: 房屋大小,單位平米
- Year: 房屋建筑年代
- Price: 房屋總價
2. 查看缺失值以及變量類型
rawdata.info()可以看到-
- 變量類型都符合預期,其中數值型變量的類型均為int64,不需要進行進一步處理;
- 只有Elevator有缺失值,并且缺失數量并不少,之后需要進一步處理。
3. 查看重復值
在查看重復值時,發現真的有,但是打印出來查看的時候沒有發現真的重復;沒有找到原因,但是還是將重復的刪掉了。
4. 處理缺失值
發現有6種情況:‘NaN’'無電梯', '有電梯', '毛坯', '精裝', '簡裝';因為數據抓取時有串行,導致數據不正確,所以刪除 '毛坯', '精裝', '簡裝';同時考慮樓房6層以下的無電梯,高層有電梯對缺失值進行填補,不過考慮Floor顯示的只是此房源樓層而不是小區樓層,可能有誤差。分析結果應該謹慎參考。
#缺失值處理 df.loc[(df['Elevator'].isnull())&(df['Floor']>6),'Elevator']='有電梯' df.loc[(df['Elevator'].isnull())&(df['Floor']<=6),'Elevator']='無電梯' del_row=df[(df['Elevator'] == '毛坯')|(df['Elevator'] == '簡裝')|(df['Elevator'] == '精裝')].index.tolist() len(del_row) df=df.drop(del_row).reset_index(drop=True) df.info()5. 查看數據的一般描述統計值
df.describe()可以看到:
- 樓層分布在1到57層,75%集中在20層以下;
- Id沒有實際意義,可以去掉;
- 每套房子總價在60W-6000W之間;75%價格小于710萬,所以6000W有些異常;
- 房子面積在15平-1019平之間;75%的面積小于118平,所以最高面積1019平也有些異常;
- 房子建造年代從1950到2017年。
6. 異常值處理
考慮要分析普通居民住宅,所以具體查看房屋面積進行處理。
#查看區域面積分布 f, ax1=plt.subplots(1,figsize=(15,10)) sns.boxplot(x="Region",y="Size",data=df,ax=ax1) ax1.set_title("北京各大區二手房面積分布") ax1.set_xlabel('區域') ax1.set_ylabel('二手房面積') plt.xticks(fontsize=9) plt.show()可以看到:
- 懷柔的房屋面積分布范圍明顯比其他城區廣,具體查看數據,的確是建筑的居民樓面積較大。考慮其地理位置,數據情況和實際相符;
- 面積小于20的查看了,無明顯異常;
- 面積大于800的幾個房源很明顯。單獨查看發現其中“新華聯科技大廈”1房間0衛有1019平,明顯不是居民住宅,需要刪除;同時考慮“X房間0衛”也看起來也不像是居民住宅;
進一步查看,戶型分布,從邏輯上看是否有需要刪除的異常值。發現有“X房間0衛”和“X室0廳”有很多;分布查看數據后發現“X室0廳”符合居民住宅情況,最后決定刪除所有的“X房間0衛”。
#戶型面積分布 f, ax1=plt.subplots(1,figsize=(10,10)) sns.boxplot(y="Layout",x="Size",data=df,ax=ax1) ax1.set_title("北京二手房戶型面積分布") ax1.set_xlabel('戶型') ax1.set_ylabel('二手房面積') plt.xticks(fontsize=9) plt.show()#找到需要刪除的行 del_list=df.loc[(df['Layout']=='5房間0衛')|(df['Layout']=='3房間0衛')|(df['Layout']=='2房間0衛')|(df['Layout']=='1房間0衛')].index.tolist() del_list df=df.drop(del_list) #刪除x房間0衛7. 變量選取
- 刪除變量“Id”因為沒有實際意義;
- 增加每平米單價“PerPrice”便于之后分析;
- 重新設置變量位置,方便查看。
Part 2 - 北京市房源分布
# 北京二手房分布情況 %matplotlib inline sns.set_style({'font.sans-serif':['simhei','Arial']}) f, [ax1,ax2,ax3] = plt.subplots(3,1, figsize=(15, 5)) sns.distplot(df['Size'], bins=30, ax=ax1, color='r') sns.kdeplot(df['Size'], shade=True, ax=ax1) sns.distplot(df['Price'], bins=30, ax=ax2, color='r') sns.kdeplot(df['Price'], shade=True, ax=ax2) sns.distplot(df['PerPrice'], bins=30, ax=ax3, color='r') sns.kdeplot(df['PerPrice'], shade=True, ax=ax3) plt.show()- 房間面積集中在0-200平以內,更大面積的房源面積變化范圍大但數量很少;
- 二手房總價集中在1000W以內;
- 二手房每平米均價在4W左右最多,但均價的分布明顯更加分散從3W-10W的房源數量都不算少。
Part 3 - 各城區房源分布
# 對二手房區域分組對比二手房數量 df_house_count = df.groupby('Region')['Price'].count().sort_values(ascending=False).to_frame().reset_index()#正確顯示中文以及負號 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False sns.set_style({'font.sans-serif':['SimHei','Arial']})f,ax=plt.subplots(1,1,figsize=(20,10)) sns.barplot(x='Region', y='Price',palette="Greens_d", data=df_house_count) ax.set_title('北京各大區二手房數量對比') ax.set_xlabel('區域') ax.set_ylabel('數量') plt.xticks(fontsize=9)#減小字體以免變成方框 plt.show()- 豐臺、海淀、朝陽和昌平數量相近,在第一梯隊;西城和大興數量相近,在第二梯隊;平谷、懷柔和密云數量非常少;
Part 4 - 各城區房價分布
- 東西城、海淀、懷柔和朝陽的平均每套二手房總價相近,在第一梯隊;除懷柔外,每平米單價也保持和總價一樣的排名;懷柔的均價并不在第一梯隊,結合之前的房屋面積,因為懷柔二手房的房屋面積較大,造成總價較高;
- 東西城、海淀和朝陽的二手房總價分布也非常接近,懷柔的價格分布范圍較廣;
- 平谷、密云、門頭溝和房山4個區域的房子總價和單價都很低,尤其是平谷和密云;為什么懷柔的二手房情況要遠遠好于它們,有待考證。
2. 房價Top15小區
#查看房屋總價最貴的小區 totalp_village = df.groupby(['Garden','Region'])['Price'].mean().sort_values(ascending = False).reset_index().head(15) totalp_village #城區分布 Topdis_check=totalp_village.groupby('Region')['Price'].count().sort_values(ascending = False).reset_index() Topdis_check#查看單價最貴的小區 Perp_village = df.groupby(['Garden','Region'])['PerPrice'].mean().sort_values(ascending = False).reset_index().head(15) Perp_village #對應城區分布 Perdis_check=Perp_village.groupby('Region')['PerPrice'].count().sort_values(ascending = False).reset_index() Perdis_check- Top結果與區域價格分析一致,貴的小區集中在西城東城,如果看總價的話,還有城六區外的順義和昌平有小區入選。
Part 5 - 各區域房屋面積分布
按照前面對于Size的查看,以區間[0,50)、[50,100)、[100,150)、[150,200)、[200,+∞)為劃分標準,將面積劃分為Mini small、small、medium、big、huge五個等級,分別對應極小戶型、小戶型、中等戶型、大戶型和巨大戶型。
df.loc[(df['Size']>=0)&(df['Size']<50),'Size_level']="Mini Small" df.loc[(df['Size']>=50)&(df['Size']<100),'Size_level']="Small" df.loc[(df['Size']>=100)&(df['Size']<150),'Size_level']="Mediumn" df.loc[(df['Size']>=150)&(df['Size']<200),'Size_level']="Big" df.loc[(df['Size']>=200),'Size_level']="Huge" df_sizelevel_count=df.groupby('Size_level')['Price'].count().sort_values(ascending=False).to_frame().reset_index()# 對二手房面積分類后對比二手房數量,總價和每平米房價 df_house_count1 = df.groupby('Size_level')['Price'].count().sort_values(ascending=False).to_frame().reset_index() df_house_mean1 = df.groupby('Size_level')['PerPrice'].mean().sort_values(ascending=False).to_frame().reset_index()f, [ax1,ax2,ax3] = plt.subplots(1,3,figsize=(15,5))sns.barplot(x='Size_level', y='Price', palette="Greens_d", data=df_house_count1, ax=ax1) ax1.set_title('北京各類別二手房數量對比') ax1.set_xlabel('類別') ax1.set_ylabel('數量') sns.boxplot(x='Size_level', y='Price', data=df, ax=ax2) ax2.set_title('北京類別二手房房屋總價') ax2.set_xlabel('類別') ax2.set_ylabel('房屋總價') sns.barplot(x='Size_level', y='PerPrice', palette="Blues_d", data=df_house_mean1, ax=ax3) ax3.set_title('北京各類別二手房每平米單價對比') ax3.set_xlabel('類別') ax3.set_ylabel('每平米單價') plt.show()- 市場上最多的二手房面積在[50,100)內,[100,150)次之;
- 從房屋總價來看,超小戶型<小戶型<中等戶型,并且三類價格比較集中;
- 從每平米單價來看,超小戶型最高,其余幾類差別不算太大,結合房屋總價,可能跟供需關系有關,總價低的市場需求量大,而相對供給量較低。
Part 6 - 房價與房源特性的關系
考慮之前的戶型非常多,寫法不一,根據全部的分布情況,只選取數量大于10套的戶型進行可視化查看。因為戶型分類較多,沒有看到特別明顯的和房價的關系。
#房每平米均價/數量和戶型 df_layout_count1=df.groupby('Layout')['PerPrice'].count().sort_values(ascending=False).to_frame().reset_index().head(26) sel_layout=df_layout_count1['Layout'].tolist() df2=df.loc[df['Layout'].isin(sel_layout)] df_layout_perprice1=df2.groupby('Layout')['PerPrice'].mean().sort_values(ascending=False).to_frame().reset_index().head(26) plt.figure(figsize=(15,5)) x=np.arange(df_layout_perprice1.shape[0]) plt.bar(x*3+1, df_layout_perprice1['PerPrice']) plt.title('房屋戶型均價') plt.xticks(x*3+1.5,df_layout_perprice1['Layout'],fontsize=8) plt.xlabel('房屋戶型') plt.ylabel('均價') plt.show()2. 房價與朝向分布
統計發現朝向的寫法非常亂,所以選取朝向套數>100的進行可視化查看。發現房屋朝向與房屋價格并沒有什么明顯的關系。
#房均價/數量和朝向 sel_direct=df['Direction'].value_counts().to_frame() sel_direct_list=sel_direct.loc[sel_direct['Direction']>100].index.tolist() df_direct=df.loc[df['Direction'].isin(sel_direct_list)] df_direct['Direction'].value_counts()# 對二手房朝向 df_house_count2 = df_direct.groupby('Direction')['Price'].count().sort_values(ascending=False).to_frame().reset_index() df_house_mean2 = df_direct.groupby('Direction')['PerPrice'].mean().sort_values(ascending=False).to_frame().reset_index()f, [ax1,ax2,ax3] = plt.subplots(3,1,figsize=(10,15))sns.barplot(x='Direction', y='Price', palette="Greens_d", data=df_house_count2, ax=ax1) ax1.set_title('北京各朝向二手房數量對比') ax1.set_xlabel('朝向') ax1.set_ylabel('數量') sns.boxplot(x='Direction', y='Price', data=df_direct, ax=ax2) ax2.set_title('北京各朝向二手房房屋總價') ax2.set_xlabel('朝向') ax2.set_ylabel('房屋總價') sns.barplot(x='Direction', y='PerPrice', palette="Blues_d", data=df_house_mean2, ax=ax3) ax3.set_title('北京各朝向二手房每平米單價對比') ax3.set_xlabel('朝向') ax3.set_ylabel('每平米單價') plt.show()3. 房價與裝修分布
- 在售二手房以精裝和簡裝為主;
- 毛坯房數量雖少,卻在每平單價和總價上均超過了精裝房。查看毛坯房源分布的區域和面積都很分散,沒有明顯特征,原因有待考證。
4. 房價與樓層
- 6層房源最多;
- 1層、42和57層的每平米單價明顯較高;其余層差異不大;
- 2層、3層的房屋總價分布與每平米單價表現不一致,平均總價明顯高于其他樓層。
5. 房價與電梯
電梯的數值在前面進行過填充,此處顯示有電梯的房源數量和總價都高于沒有電梯的,符合常識。但是填充的結果是否正確,也有待考證。
#房均價/數量和有無電梯 f, [ax1,ax2] = plt.subplots(1, 2, figsize=(20, 10)) sns.countplot(df['Elevator'], ax=ax1) ax1.set_title('有無電梯數量對比',fontsize=15) ax1.set_xlabel('是否有電梯') ax1.set_ylabel('數量') sns.barplot(x='Elevator', y='Price', data=df, ax=ax2) ax2.set_title('有無電梯房價對比',fontsize=15) ax2.set_xlabel('是否有電梯') ax2.set_ylabel('總價') plt.show()6. 房價與建筑年限
y1=df.groupby('Year').Price.mean().reset_index() y2=df.groupby('Year').PerPrice.count().reset_index() x=y1.Year plt.plot(x,y1.Price,label='Total Price') plt.plot(x,y2.PerPrice,'r--',label='Total Number') plt.legend(loc='best') plt.show()plt.figure(figsize=(15,5)) df.groupby('Year').PerPrice.mean().plot() plt.title('建筑時間-每平米單價')#不同城區的建筑情況 plt.figure(figsize=(15,10)) sns.swarmplot(x="Year",y="Region",data=df) plt.title('建筑時間-數量') plt.show()- 2000-2010年10年間北京大規模增加住宅,房屋總價同時增長,但整體房屋單價下降;結合不同年限各區域的住宅分布,可知這段實際增加了非內城區的其他區域的住宅,所以單價沒有增加;
- 西城的住宅建設開始的最早,1980年之后各大城區才開始建設;建設時間和城區位置相符。
小結
通過分析可以看到,二手房市場的房源數量和房價表現出的北京特征非常明顯:
- 中心城區東西城和學區房海淀朝陽房源多同時房價高;
- 房源面積集中在50-150平之內,總價均值在500-600萬,<50平的房源因為房屋數量少和總價低,反而單價最高;
- 房屋的建筑時間和北京各區域發展的時間一致;
- 房價更多與區域位置和面積相關,與戶型、裝修和電梯等等相關性不明顯。
本篇側重于鍛煉python實現數據清洗和可視化的能力,不足之處:
- 對于變量電梯、朝向、戶型等的處理非常粗糙;
- 分析的問題不夠明確,導致分析結論不明確。
參考資料:
小感悟:當目標不同時,即使數據源相同,分析的呈現思路也是完全不一樣的:1和2都是對數據有預設問題,帶著問題去看數據找到結論;3更突出探索性分析的特點,目標是為了理解完數據之后選取特征建模。
總結
以上是生活随笔為你收集整理的python建筑案例_Python数据分析实战-链家北京二手房价分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cpu只能单通道是什么表现_【小白入门】
- 下一篇: 打开git界面_使用 Gitea 快速搭