前言
通过爬虫爬取了武汉2019年7月的二手房数据,并对这些数据进行了数据分析。
- 因为链家有反爬虫机制,所以只能显示100页,一共有3000条数据。
- 数据量比较少,对于武汉二手房的分析侧重于分析思路。
- 爬虫是使用PyCharm运行,使用了requests库,后续大的需求会学习使用Scrapy框架。
下面是爬虫代码:
import requests
import re
import lxml
from bs4 import BeautifulSoup
with open('jianjia.csv','a',encoding='utf-8') as f:
#创建房源数据文件
page = 100
for i in range(1, page+1):
url = 'https://wh.lianjia.com/ershoufang/pg%s' % i
header = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3704.400 QQBrowser/10.4.3587.400'
}
# 设置请求头
resp = requests.get(url, headers=header)
resp.encoding = 'utf-8'
# resp.text #得到的文本格式的网页源码
# resp.content.decode('utf-8') #得到的是二进制格式网页源码,然后用decode来进行解码
html = resp.text
soup = BeautifulSoup(html, 'lxml')
infos = soup.find('ul', {'class': 'sellListContent'}).find_all('li')
for info in infos:
title = info.find(
'div', {'class': 'info clear'}).find('div', {'class': 'title'}).find('a').get_text()
adress = info.find('div',{'class':'houseInfo'}).get_text()
position = info.find('div',{'class':'positionInfo'}).get_text()
totalPrice = info.find('div',{'class':'totalPrice'}).find('span').get_text()
unitPrice = info.find('div',{'class':'unitPrice'}).find('span').get_text()
list = re.split(r'\|', adress)
info_url = info.find('div',{'class':'title'}).find('a').get("href")
# 获得每个房源信息的url
print(list)
info_resp = requests.get(info_url, headers=header)
info_resp.encoding = 'utf-8'
info_html = info_resp.text
info_soup = BeautifulSoup(info_html, 'lxml')
district = info_soup.find(
'div', {'class': 'areaName'}).find('span',{'class':'info'}).find('a').get_text()
f.write('{},{},{},{},{}\n'.format(
list,position,unitPrice,totalPrice,district))
#得到最终房源数据文件,代码中未设置超时处理。
- 爬取完武汉二手房数据后,得到了lianjia.csv数据文件。
分析思路
- 数据清洗
- 各个城区二手房房源分布
- 各个城区二手房总面积和平均面积分布
- 各个城区二手房房源总价和单价分布
- 房价与户型、楼层、朝向、建筑年代的关系
导入数据
导入第三方包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
解决中文和负值无法显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.style.use('ggplot')
sns.set(font='SimHei')
创建字段,导入数据
columns = ['name','house_type','area','orientations','decoration','adress','unit_price','total_price','district']
df = pd.read_csv('lianjia.csv',encoding = 'UTF-8',names = columns)
1. 数据清洗
查看数据,显示前五行。
df.head()
清洗数据中的多余符号和空格
df.iloc[:,0] = df.iloc[:,0].str.replace('[','').str.replace(']','').str.replace(' ','').str.replace('\'','')
df['house_type'] = df['house_type'].str.replace('[','').str.replace(']','').str.replace(' ','').str.replace('\'','')
df['area'] = df['area'].str.replace('[','').str.replace(']','').str.replace(' ','').str.replace('\'','')
df['orientations'] = df['orientations'].str.replace('\' ','').str.replace(' \'','')
df['decoration'] = df['decoration'].str.replace('[','').str.replace(']','').str.replace(' ','').str.replace('\'','')
# 清洗数据中多余的空格和符号
df['unit_price'] = df['unit_price'].str.extract('(\d+)元').astype(int)
df['area'] = df['area'].str.replace('平米','').astype(float)
# 利用extract函数和正则表达式提取单价,再转为整型格式。
df['construction_time'] = df['adress'].str.extract('(\d+)年').astype(float)
df['floor_level'] = df['adress'].apply(lambda x: x[0:3])
# 提取楼层信息
df['construction_time'] = df['adress'].str.extract('(\d+)年').astype(float)
df['floor'] = df['adress'].str.extract('共(\d+)层').astype(float)
df.drop(['adress'],inplace=True,axis=1)
# 删除原有adress列
清洗完成后,再次查看数据
df.head()
1.1 查看数据类型
df.info()
1.2 查看数据缺失情况
df.isnull().sum()
- 建筑时间和楼层有缺失数据
1.3 描述统计
df.describe()
- 由描述统计得到以下信息:
- 平均面积为101.9㎡,其中面积中位数为94.5㎡。平均数大于中位数,面积为右偏分布,由少数大面积的房源拉高了整体水平。
- 房屋总价的平均值是202.9万元,其中中位数为180万元。同样为右偏分布,存在少数高总价房源。
- 房屋单价平均数为19739元,中位数是19027元,平均值和中位数基本相同,说明房价升高趋势呈线性。
2. 各个城区二手房房源分布
2.1 武汉市辖区信息
df.describe()
武汉全市下辖13个市辖区,分别是:
- 中心城区:江岸区、江汉区、桥口区、武昌区、青山区、洪山区、汉阳区
- 郊区:蔡甸区、汉南区、江夏区、黄陂区、新洲区,东西湖区
- 另有两个开发区:东湖高新、沌口开发区
2.2 各个城区房源数量
district_num = df.district.value_counts().reset_index().sort_values('district',ascending = False)
district_num
- 按房源数排序,数量最多的是洪山区,数量最少的是新洲区。
各个城区房源数分布柱形图
plt.figure(figsize=(10,4))
plt.subplot(1,1,1)
sns.barplot(x='index',y='district',data = district_num,palette=sns.color_palette("GnBu_d"))
plt.title('各个城区房源数量')
plt.xlabel('城区')
plt.ylabel('数量')
plt.show()
- 由上图可知,所有的中心城区二手房数量都超过了200套。数量最多的是洪山区,数量为637套。
3. 各个城区二手房总面积和平均面积分布
3.1 各个城区二手房总面积
按城区聚合数据
grouped_total_area = df.groupby('district').sum().sort_values('area',ascending= False).reset_index()
grouped_total_area
各城区总面积分布折线图
plt.figure(figsize=(10,4))
plt.subplot(1,1,1)
plt.plot(grouped_total_area['district'],grouped_total_area['area'])
plt.title('各城区总面积分布')
plt.xlabel('城区')
plt.ylabel('数量')
plt.show()
-
由上图可知总面积排名前三的是:洪山区、江岸区和东湖高新。与拥有的房源数排名一致。
查阅武汉市各个辖区的面积和人口,由此知房源数量和房屋总面积与辖区面积无关。
3.2 各个城区二手房总面积
按城区聚合数据得到平均面积数据
grouped_mean_area = df.groupby('district').mean().sort_values('area',ascending = False).reset_index()
grouped_mean_area
各个城区平均房源面积折线图
fig,ax1 = plt.subplots(1,1,figsize=(10,6))
ax1.plot(grouped_mean_area['district'],grouped_mean_area['area'],label = '平均面积')
ax1.legend(loc=3)
# label设置图例,legend显示图例,loc设置位置
ax2 = ax1.twinx()
ax2.plot(grouped_mean_area['district'],grouped_mean_area['unit_price'],color= 'g',label = '平均单价')
ax2.legend(loc=8)
plt.title('各城区平均面积分布')
ax1.set_xlabel('城区')
ax1.set_ylabel('面积')
ax2.set_ylabel('单价')
plt.show()
- 由上面折线图可知,蔡甸区平均面积最多。但是,平均价格不高。并且,蔡甸区的房源数不多。分析原因可能是因为不在中心城区,建设成本低,所以房屋面积大,且房价不高。
- 各个城区的总面积和平均面积的差别较大,没有什么明显趋势,可能是房源数据量太少的原因。
3.3 全市平均面积等级划分
- 将面积划分为5个等级
- tinysmall: 超小户型
- small: 小户型
- medium: 中等户型
- big: 大户型
- huge: 超大户型
df['area_level'] = pd.cut(df.area, bins=[0,50,100,150,200,500],labels=['tinysmall','small','medium','big','huge'])
df.head()
各个户型的房源数
grouped_area_level = df.groupby('area_level').name.count().reset_index()
grouped_area_level
fig,ax = plt.subplots(1,1,figsize=(8,4))
plt.bar(grouped_area_level.area_level,grouped_area_level.name)
plt.title('各户型数量分布')
plt.tick_params(labelsize=14)
plt.show()
各个户型数量的柱形图
- 由上图可知:
- 平均面积为small的房源占总数的50%,面积在区间(50,100]㎡。
- 平均面积为medium的房源约占总数的36%,面积在区间(100,150]㎡。
- 剩下的面积房源约占14%,比例不高。
4. 各城区房屋总价和单价
4.1 总价分析
df.boxplot(column = 'total_price', by = 'district',figsize=(12,6))
# 箱线图的大小在内部设置
plt.title('各城区总价箱线图')
plt.xlabel('城区')
plt.show()
各个城区总价平均值排名
df.groupby('district').mean().sort_values('total_price',ascending = False).total_price.reset_index()
- 右上述结果可知:
- 总价第一名为武昌区,平均值为258万元,中位数小于平均值,呈右偏分布,有少数总价高的房源拉高总体平均值。
- 沌口开发区的平均值为144万元,与中位数相差不大,总价上升比较线性。
- 新洲区总价不高,且平均值接近中位数,总价最大值才88万。
plt.figure(figsize=(8,4))
plt.hist(df.total_price,bins=40)
plt.title('总价分布图')
plt.show()
- 总价分布是一个右偏分布,说明有少量总价高的房源拉高总体平均值。多数房源集中在[150,200]区间。
4.2 单价分析
df.boxplot(column = 'unit_price', by = 'district',figsize=(12,6))
# 箱线图的大小在内部设置
plt.title('各城区单价箱线图')
plt.xlabel('城区')
plt.show()
各个城区单价平均值排名
unit_mean_price = df.groupby('district').mean().sort_values('unit_price',ascending = False).unit_price.reset_index()
unit_mean_price
- 由以上结果可知:
- 单价第一名是武昌区,平均单价为25154元,与中位数接近,接近正态分布,分布增长趋势呈线性。
- 第二名是江汉区,平均单价为21322元,超过20000元。
- 第三名是洪山区,平均单价为20852元,房源数量最多,同样与中位数接近。
- 第四名是东湖高新,平均单价为20614元,在超过20000元单价的城区中,唯一一个不是主城区的,可能和新区发展和各个高新企业进驻有很大关系。
plt.figure(figsize=(8,4))
plt.hist(df.unit_price,bins=30)
plt.title('全市单价分布图')
plt.show()
- 单价直方图接近正态分布,70%的单价都在区间[15000,25000]元,基本反映了武汉市整体的二手房单价。
4.3 总价和单价排名前15的小区
grouped_name_count = df.groupby('name').count()
grouped_name_mean = df.groupby('name').mean()
grouped_name_count.sort_values('total_price',ascending=False)['total_price'].reset_index().head()
- 房源数排名前五的小区。
总价排名前15的小区
grouped_total_price_rank = grouped_name_mean.sort_values('total_price',ascending=False).reset_index()
grouped_total_price_rank.head(15)
plt.figure(figsize=(16,4))
plt.bar(grouped_total_price_rank.head(15).name,grouped_total_price_rank.head(15)['total_price'])
plt.title('平均总价排名前15的小区')
plt.xticks(rotation = -60)
plt.show()
- 全市总价排名第一的小区是武汉天地四期B11,总价为1500万元。
- 第二名是武汉天地云廷,总价为1428万元,同样是位于武汉天地,说明武汉天地总价在武汉独一档。
- 第三名是泛海国际香海园,总价为1418万元,只有三个小区总价超过1000万。
- 在前15名的小区中,武汉天地的小区有3个,说明该地段是豪宅林立。
单价排名前15的小区
grouped_unit_price_rank = grouped_name_mean.sort_values('unit_price',ascending=False).reset_index()
grouped_unit_price_rank.head(15)
plt.figure(figsize=(16,4))
plt.bar(grouped_unit_price_rank.head(15).name,grouped_unit_price_rank.head(15)['unit_price'])
plt.title('平均单价排名前15的小区')
plt.xticks(rotation = -60)
plt.show()
- 全市总价排名第一的小区是洞庭苑,单价为61530元。
- 第2-4名都是武汉天地的小区,说明总价高,单价也是一定会高。
- 复地东湖国际也有5个小区上榜,该小区也同样是寸土寸金的小区。
- 武汉二师教工宿舍排名第8,位于中南路旁,属于武昌核心地段,学校,医院,银行,商圈配套齐全,虽然房源很老,但是房价依然很贵。
5. 房价与户型、楼层、装修、建筑年代的关系
5.1 房价与户型的关系
各个户型的房源数量
grouped_house_type_count = df.groupby('house_type').count().sort_values('name',ascending = False).name.reset_index()
grouped_house_type_count
plt.figure(figsize=(16,4))
plt.bar(grouped_house_type_count.house_type,grouped_house_type_count.name)
plt.title('各个户型数量')
plt.show()
各个户型的平均单价
grouped_house_type_mean = df.groupby('house_type').mean().sort_values('unit_price',ascending = False).unit_price.reset_index()
grouped_house_type_mean
plt.figure(figsize=(16,4))
plt.bar(grouped_house_type_mean.house_type,grouped_house_type_mean.unit_price)
plt.title('户型-单价图')
plt.show()
- 综上可得知:
- 房源最多的户型是3室2厅,但是这种户型的平均单价并不是最高,为19583元。
- 单价超过20000的户型,所占房源都不多,可能是房源数量太少的原因,这些户型都是冷门户型。
- 3室2厅、2室2厅、2室1厅、4室2厅、3室1厅、1室1厅所占房源数量比较多,说明中小户型比较受欢迎,其总价不高。其中3室2厅为最热门户型。
5.2 房价与楼层的关系
楼层等级与房源数
grouped_floor_level_count = df.groupby('floor_level').count().sort_values(
'name',ascending = False).name.reset_index().query('name>20')
# 也可用loc按行切片loc[name>20],去除少于20套的脏数据
grouped_floor_level_count
plt.figure(figsize=(10,4))
plt.bar(grouped_floor_level_count.floor_level,grouped_floor_level_count.name)
plt.title('楼层等级-数量')
plt.show()
- 由上图可知中楼层数量最多,数量超过1000套,剩下高楼层、低楼层依次递减。整体相差都不大。
楼层等级与单价
grouped_floor_level_mean = df.groupby('floor_level').mean().sort_values(
'unit_price',ascending = False).unit_price.reset_index().query('unit_price>19400 and unit_price<20200')
grouped_floor_level_mean
plt.figure(figsize=(10,4))
plt.bar(grouped_floor_level_mean.floor_level,grouped_floor_level_mean.unit_price)
plt.title('楼层等级-单价')
plt.show()
- 由上图可知各个楼层的单价相差都不大,在20000元左右。
楼层等级与总价
grouped_floor_level_total = df.groupby('floor_level').mean().sort_values(
'total_price',ascending = False).total_price.reset_index().query('190
plt.figure(figsize=(10,4))
plt.bar(grouped_floor_level_total.floor_level,grouped_floor_level_total.total_price)
plt.title('楼层等级-总价')
plt.show()
- 由上图可知各个楼层的总价相差都不大,在200万元左右。
楼层与单价的关系
查看数据空值
df.isnull().sum()
删除空值行
df.floor = df.floor.fillna('666')
# 填充空值为666
a_list = df[df.floor == '666'].index.tolist()
# 得到值为666的索引
df2 = df.drop(a_list)
# 删除666的索引
df2.isnull().sum()
df2.groupby('floor').mean().sort_values('unit_price',ascending = False).unit_price.reset_index().head(15)
plt.figure(figsize=(10,4))
df2.groupby('floor').unit_price.mean().plot()
plt.title('楼层-单价')
plt.show()
- 由上图分析可知,随着楼层输的增加,房价也随之升高,线性关系不明显。超过40层之后房价随楼层数增加而增加的趋势波动很大,可能的原因是楼层数超过40的住宅数量较小,超过40层的数据量比较小,容易产生误差。
5.3 房价与装修的关系
查看各种装修的房源数
df.groupby('decoration').count()['name']
按装修聚合得到数据
grouped_decoration = df.groupby('decoration').mean().reset_index()
grouped_decoration
装修和平均面积、单价和总价的关系
plt.figure(figsize=(18,4))
plt.subplot(1,3,1)
plt.bar(grouped_decoration.decoration,grouped_decoration.area)
plt.title('装修-面积')
plt.subplot(1,3,2)
plt.bar(grouped_decoration.decoration,grouped_decoration.unit_price)
plt.title('装修-单价')
plt.subplot(1,3,3)
plt.bar(grouped_decoration.decoration,grouped_decoration.total_price)
plt.title('装修-总价')
plt.show()
- 不同装修的平均面积大致相等,差别不大。
- 平均单价按其他、毛坯、简装、精装依次递增,说明装修成本是影响单价的重要因素。
- 总价和装修的关系不大,应该是和面积有决定关系。
5.4 房价与建筑年代的关系
删除为空的数据行
df.construction_time = df.construction_time.fillna('111')
b_list = df[df.construction_time == '111'].index.tolist()
df2 = df.drop(b_list)
df2.isnull().sum()
建筑时间和房源数、单价和总价的关系
plt.figure(figsize=(12,16))
plt.subplot(3,1,1)
df2.groupby('construction_time').unit_price.count().plot()
plt.title('建筑时间-数量')
plt.subplot(3,1,2)
df2.groupby('construction_time').unit_price.mean().plot()
plt.title('建筑时间-平均单价')
plt.subplot(3,1,3)
df2.groupby('construction_time').total_price.mean().plot()
plt.title('建筑时间-平均总价')
plt.show()
- 由以上分析可知:
- 房屋数在90年代新建数一直在50套左右缓慢的上升,在2000后急速增长,于2015年达到顶峰。
- 建造时间在90年代的房屋,单价和总价普遍高于后来建成房屋。原因可能是建造时间早,地段处于现在的核心位置,交通、医疗、教育等配套设施完善。
- 2015年后房屋数量和价格有下降趋势,这与目前的实际形势有些差异,可能是因为2015年后的房源数太少,而造成的数据干扰。
总结
- 武汉市2019年二手房整体均价在20000元左右。
- 中心城区房价和房源数相对都很高很多。
- 绝大多数的二手房都为精装修房,购房户可以省下装修费用,但是,实际装修效果还是要现场查看。
- 2000年左右建成的房子,相对来说价格不会太高,且建成时间也不近,附近的配套设施也会比较完善。
- 总体来看,武汉市二手房房价还是呈上升的趋势。