python建筑案例_Python数据分析实战-链家北京二手房价分析
前言
最近在自学Python,通过学习大家的分享案例,看到使用Python进行较多的主要4个方面:爬虫,数据处理,数据可视化以及机器学习建模。对我来说目标就是:
- 熟练使用numpy pandas 进行数据清洗和预处理;
- 熟练使用pandas进行数据统计;
- 熟练使用matplotlib seaborn进行数据可视化;
- 了解机器学习常用算法,并能够做一个项目。
我将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”便于之后分析;
- 重新设置变量位置,方便查看。
#选取子集
df=df.drop(['Id'],axis=1).reset_index(drop=True)
# 添加新特征房屋均价
df['PerPrice'] =df['Price']/df['Size']
# 重新摆放列位置
columns = ['Region', 'District', 'Garden', 'Layout', 'Floor', 'Year', 'Size', 'Elevator', 'Direction', 'Renovation', 'PerPrice', 'Price']
df = pd.DataFrame(df, columns = columns)
df.head()
df.describe()
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 - 各城区房价分布
- 各区域总价以及每平米均价分布
#各城区房平均总价分布
df_price_mean=df.groupby("Region")["Price"].mean().sort_values(ascending=False).to_frame().reset_index()
f,[ax1,ax2]=plt.subplots(2,1,figsize=(20,15))
sns.barplot(x="Region",y="Price",palette="Blues_d",data=df_price_mean,ax=ax1)
ax1.set_title("北京各大区二手房总价对比")
ax1.set_xlabel('区域')
ax1.set_ylabel('总价(区域均值)')sns.boxplot(x="Region",y="Price",data=df,ax=ax2)
ax2.set_title("北京各大区二手房总价分布")
ax2.set_xlabel('区域')
ax2.set_ylabel('总价')
plt.xticks(fontsize=9)
plt.show()
#各城区房每平米单价分布
df_perprice_mean=df.groupby("Region")["PerPrice"].mean().sort_values(ascending=False).to_frame().reset_index()
f,[ax1,ax2]=plt.subplots(2,1,figsize=(20,15))
sns.barplot(x="Region",y="PerPrice",palette="Blues_d",data=df_perprice_mean,ax=ax1)
ax1.set_title("北京各大区二手房每平米单价对比")
ax1.set_xlabel('区域')
ax1.set_ylabel('每平米单价')sns.boxplot(x="Region",y="PerPrice",palette="Blues_d",data=df,ax=ax2)
ax2.set_title("北京各大区二手房每平米单价分布")
ax2.set_xlabel('区域')
ax2.set_ylabel('每平米单价')
plt.xticks(fontsize=9)
plt.show()
- 东西城、海淀、怀柔和朝阳的平均每套二手房总价相近,在第一梯队;除怀柔外,每平米单价也保持和总价一样的排名;怀柔的均价并不在第一梯队,结合之前的房屋面积,因为怀柔二手房的房屋面积较大,造成总价较高;
- 东西城、海淀和朝阳的二手房总价分布也非常接近,怀柔的价格分布范围较广;
- 平谷、密云、门头沟和房山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. 房价与装修分布
- 在售二手房以精装和简装为主;
- 毛坯房数量虽少,却在每平单价和总价上均超过了精装房。查看毛坯房源分布的区域和面积都很分散,没有明显特征,原因有待考证。
#房均价/数量和装修
df['Renovation'].value_counts()
# 画幅设置
f, [ax1,ax2,ax3] = plt.subplots(1, 3, figsize=(15, 5))
sns.countplot(df['Renovation'], ax=ax1)
sns.barplot(x='Renovation', y='Price', data=df, ax=ax2)
sns.boxplot(x='Renovation', y='Price', data=df, ax=ax3)
plt.show()
4. 房价与楼层
- 6层房源最多;
- 1层、42和57层的每平米单价明显较高;其余层差异不大;
- 2层、3层的房屋总价分布与每平米单价表现不一致,平均总价明显高于其他楼层。
#房均价/数量和楼层
df['Floor'].value_counts()f, [ax1,ax2,ax3] = plt.subplots(3, 1, figsize=(20, 10))
sns.countplot(df['Floor'], ax=ax1)
sns.barplot(x='Floor', y='PerPrice', data=df, ax=ax2)
sns.boxplot(x='Floor', y='Price', data=df, ax=ax3)
plt.show()
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实现数据清洗和可视化的能力,不足之处:
- 对于变量电梯、朝向、户型等的处理非常粗糙;
- 分析的问题不够明确,导致分析结论不明确。
参考资料:
- 第二篇数据分析项目实战:链家二手房分析
- 乐天:Python进行电影数据分析及可视化
- 路远:入门Python数据分析最好的实战项目(一)分析篇
小感悟:当目标不同时,即使数据源相同,分析的呈现思路也是完全不一样的:1和2都是对数据有预设问题,带着问题去看数据找到结论;3更突出探索性分析的特点,目标是为了理解完数据之后选取特征建模。
python建筑案例_Python数据分析实战-链家北京二手房价分析相关推荐
- 爬虫实战-链家北京房租数据
爬虫实战-链家北京房租数据 本篇是对 恋习Python 发布的原创文章<北京房租大涨?6个维度,数万条数据帮你揭穿>中涉及的代码部分的解读. < 在复现原文代码时,出现了一些报错,在 ...
- python数据分析项目实战—————链家北京租房数据统计分析
链家北京租房数据分析 1.读取数据 import pandas as pd import matplotlib.pyplot as plt import numpy as npdata_dframe ...
- python找房源_python抓取链家房源信息(二)
试着用scrapy将之前写的抓取链家网信息的重新写了写 然后先是用了第一页的网页作为测试,调试代码,然后发现总是抓取的时候遇见了 类似于这样的问题,并且抓取不到信息 2017-03-28 17:52: ...
- 多进程+多线程爬取链家武汉二手房价
因为数据分析的需要,就写了爬取链家武汉的数据.因为用scrapy框架感觉太慢了,就自己写了个多进程同步执行的代码. 1.数据量:20000+ 2.程序环境:Python3.6--->用的Anac ...
- python聚类分析案例_python 聚类分析实战案例:K-means算法(原理源码)
K-means算法: 关于步骤:参考之前的博客 关于代码与数据:暂时整理代码如下:后期会附上github地址,上传原始数据与代码完整版, 各种聚类算法的对比:参考连接 Kmeans算法的缺陷 1.聚类 ...
- python因子分析案例_python数据分析单因子分析
集中趋势 均值 panda.mean() 分位数 panda.quantile(q) q = 0.25 Q1 = (n+1)0.25 q = 0.5 中位数 Q1 = (n+1)0.5 q = 0.7 ...
- Selenium+ChromeDriver爬取链家网二手房价(包括经纬度)信息
[需求] 爬取青岛市二手房源信息,要求包括房源基本信息.小区名称.总价.单价以及房源的经纬度信息. 根据以上需求,进入青岛市二手房首页,如图1所示,进行页面分析: 图1 [页面分析] 首先 ...
- 数据挖掘与数据分析项目链家租房数据(一)数据爬虫
数据挖掘与数据分析项目链家租房数据(一)数据爬虫 今日无聊将一个过去做的链家数据分析项目弄上来,当时是某面试,三天时间完成,主要是供大家抄代码和分享一下思考点,这一章是爬虫部分. 网站原图 结果截图 ...
- 基于python多线程和Scrapy爬取链家网房价成交信息
文章目录 知识背景 Scrapy- spider 爬虫框架 SQLite数据库 python多线程 爬取流程详解 爬取房价信息 封装数据库类,方便多线程操作 数据库插入操作 构建爬虫爬取数据 基于百度 ...
最新文章
- vi 方向键和Backspace键失效问题的解决方法
- 跟我一起写操作系统(二)——史上最简单的内核
- java中字符串的精确匹配_Java最佳实践–字符串性能和精确字符串匹配
- 前端学习(3139):react-hello-react之生命周期组件挂载过程
- org.hibernate.MappingException: Could not determine type for: java.util.List, at table: user, for...
- 腾讯智慧出行和现代汽车集团创新中心(北京)正式建立创新战略合作伙伴关系
- 《软件项目管理(第二版)》第 3 章——项目计划 重点部分总结
- RTT的内存管理篇——为什么要进行内存管理?
- 捋一捋20201217
- 拼多多年货节上线,“百亿补贴”加码iPhone 12等产品
- ios php mysql实例_如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1
- 基于图像界面工具postman进行测试
- NYOJ 588 Money
- html输入框素材,html文本框代码
- 电力系统服务器是什么,什么是电网调度?
- idea 2021 IDEA的Persistence 窗口 查看ERD关系图
- 创造一颗属于你的星球
- Ubuntu及window的配置 java变量和快捷键
- 2018秋c语言程序设计考试答案,2018年自学考试《C语言程序设计》模拟试题【四篇】...
- 不小心点了计算机一键还原怎么操作,电脑按了一键还原系统怎么办
热门文章
- 爬取Github Web API 并存入Mysql数据库
- java controller json_springMVC的controller层接收前端json数据
- 中富之命能有多少钱_邯郸白铁风管工每天工资多少钱?白铁风管价格多少钱你能接受?...
- execel公式 java工具_PAP-快速开发框架:JAVA 计算器 自定义公式 解决EXCEL计算公式问题...
- 主成分分析法案例_因子分析案例及操作解析
- python turtle颜色rgb_turtle绘图总结
- obs噪音抑制调多少合适_TVS瞬态抑制二极管的特性及应用
- tensorflow中创建多个计算图(Graph)
- 数字图像处理总结(冈萨雷斯版)
- Python文件拷贝函数