上海市租房信息分析

项目背景

随着毕业季和暑假的到来,各大城市又要迎来一批小鲜肉了,摆在大家面前的第一件事就是关于住宿的事了。众所周知,北上广的房价对于大多数刚毕业的或者实习的同学们来说,即使拼爹也是比较难马上定居下来的,所以租房就成了大多数人必须的选择。本项目主要通过对链家网上海地区租房信息的爬取获得数据,进行数据分析后,给出合理的建议。

项目简介

本次项目主要是利用爬虫爬取链家网上关于租房方面的信息,然后通过数据清洗和加工,从而进行一些数据探索和分析,从而对整个上海租房市场现状有个了解,并且对在上海租房做出自己的建议。

数据来源和数据集

本项目所使用的数据集全部来自链家网,是使用 requests + BeautifulSoup 的方法对页面进行抓取和数据提取。通过使用 requests 库对链家网租房列表页进行抓取,通过 BeautifulSoup 对页面进行解析,并从中获取房源小区,面积,户型和价格等数据。

具体爬取过程见:Python爬取链家网上海市租房信息

本次爬取信息的时候,主要获得了以下信息:
内容字段小区名称 name、户型 room_type、面积 size、区县 region、街道地段 area、楼层 louceng、朝向 chaoxiang、月租价格 price、地铁线subway、到地铁线的距离distance、标题title等。

目的

主要是通过实际的数据分析对上海租房市场做一个简单的介绍,给有意向在上海租房的小伙伴们提供一些参考性的意见。具体来说,主要针对以下几个问题:
1、房源的地域性分布
2、户型的影响
3、楼层的影响
4、地铁及到地铁的距离的影响
5、不同的宣传标题是否会对销售有影响?有哪些关键词?

技术和工具

本项目主要分为两大部分:
第一部分是数据爬取,采用的是 requests + BeautifulSoup。
第二部分是数据分析,以 Python 编程语言为基础。数据分析部分主要使用 pandas 作为数据整理和统计分析的工具,matplotlib 用于图形的可视化,seaborn 库包用于图形美化。在进行宣传标题分析的时候,使用了jieba 作为分词工具包,并使用 wordcloud 包制作词云。

数据整理和清洗

# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
import seaborn as sns
import jieba
import jieba.analyse
from wordcloud import WordCloud
from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei']

#从csv文件中读取数据并存入DataFrame中
df = pd.read_csv('D:/jupyter/lianjia.csv',sep = ',',encoding='gbk')  #必须得转码,否则后面显示乱码

#清理重复行
drop_df = df.drop_duplicates()

#初步观察数据情况
drop_df.info()
drop_df.describe()
drop_df.head(5)
1.png
2.png

经过数据的清洗和整理,我们可以看出,上海一共有39774套房源,平均租金为8142元/月,怎么会这么高,经过发现有个别58万/月的数据,同时楼层值为地上的房源都是别墅,数量少且租价高,需要对其再进行清洗。并且租房面积和租金有着密切的关系,改用每平方米月租金衡量(例如:总的平均月租金为8142.84/97.66=83.38元/平方米)。同时根据《上海市房屋租赁条例》,居住使用人的人均居住面积不得低于5平方米。针对以上几点对数据进行整理:

#补充缺失值
drop_df = drop_df.fillna({'distance':0,'subway':u'非地铁房'})

#清理异常值,选取租金和租房面积合适的房源
drop_df = drop_df[drop_df['louceng'] != u'地上'] #清理高价别墅房源
drop_df = drop_df[drop_df['price'] < 25000] #清理少数异常高价房源
drop_df = drop_df[drop_df['size'] > 5]  #根据上海市要求,清理租房面积小于5平米的房源

#给表格添加每平方米月租金列
Price_average = (drop_df['price'] / drop_df['size']).round(2)
drop_df['Price_average'] = Price_average
drop_df.info()
drop_df.head(5)
3.png

房源的地域性分布情况

#观察地域分布情况
count_by_region = drop_df.groupby(['region'])['name'].count()

figure = plt.figure(figsize = (12,8))
ax1 = plt.subplot(111)
rect = ax1.bar(np.arange(len(count_by_region)),count_by_region.values,width =0.6)

#设置x轴刻度标签
def auto_xticks(rects,xticks):
    x = []
    for rect in rects:
        x.append(rect.get_x() + rect.get_width()/2)
    x = tuple(x)
    plt.xticks(x,xticks)
auto_xticks(rect,count_by_region.index)

#设置数据标签数:
def auto_tag(rects, data = None, offset = [0,0]):
    for rect in rects:
        try:
            height = rect.get_height()
            plt.text(rect.get_x() + 0.1, 1.01 * height, '%s' % int(height))
        except AttributeError:
            x = range(len(data))
            y = data.values
            for i in range(len(x)):
                plt.text(x[i] - 0.2 + offset[0],y[i] + .05 + offset[1],y[i])
auto_tag(rect)
plt.legend(rect,[u'房源数量'],loc = 'upper left')

#各区每平方月租均价
Price_per_square_meter = (drop_df.groupby(['region'])['Price_average'].mean()).round(2)

#绘制每平米月租金折线图
ax2 = ax1.twinx()
x = [i for i in range(len(Price_per_square_meter))]
y = Price_per_square_meter.values
rect2 = ax2.plot(x,y,'mo-', label = 'right')
auto_tag(rect2,Price_per_square_meter)
auto_xticks(rect,Price_per_square_meter.index)

ax1.set_title(u'不同区域的房源数量及每平米月租金')
plt.legend(rect2,[u'每平米月租金'],loc = 'upper right')
4.png

从上图可以看出四分之一以上的房源位于浦东,相对于其他地方浦东似乎更容易找到租住的房子,另外闵行,徐汇也有着较多的选择,但是根据每平米租金来算,徐汇,长宁的租金更贵,所以综合来看,浦东和闵行似乎更好一点,选择比较多,租金也是在可以接受的范围内。

#观察各区的月租金箱形图
count_by_region_rent = drop_df.groupby(['region'])['price']
mm =[]
for group in count_by_region.index:
    v = count_by_region_rent.get_group(group).values
    mm.append(v)
fig = plt.figure(figsize = (10,10))
ax3 = plt.subplot(111)
rect3 = ax3.boxplot(mm)
#设置标签
ax3.set_xticklabels(count_by_region.index)
plt.yticks(range(0,30000,2500))
5.png

从箱形图中可以看出各区的月租分布差距比较大,这和上海的一线城市的地位是相同的,不仅有新来的求职者,也有工作多年的白领和成功人士,从而导致了房租的分布差距大。经过对比上海市政规划可以看出,其中徐汇、长宁、静安等月租较高的原因可能是:
1、徐汇区有上海最多的各式花园洋房,决定了区域内租房市场多为高端租房。
2、上海最集中的涉外高标准住宅商务办公综合区、虹桥路沿线和西郊宾馆周围建有许多幢花园别墅,上海市大多数外国领事馆和外交官的官邸分布在长宁,果然是真正的土豪租房优选区域。
3、静安是上海出名的小资区域,其中有多处名人故居,文化气息浓郁;而且其中高档小区与写字楼都很多,导致了租金一直居高不下等。

户型分布情况

#查看户型分布情况
count_by_room_type = drop_df.groupby(['room_type'])['name'].count().sort_values(ascending = False)

figure = plt.figure(figsize=(15,9))
ax4 = plt.subplot(111)
rect4 = ax4.bar(np.arange(len(count_by_room_type)),count_by_room_type.values,width =0.4)
auto_tag(rect4)
auto_xticks(rect4,count_by_room_type.index)
ax4.set_title(u'户型分布情况')
plt.legend(rect4,[u'房源数量'],loc = 'upper right')
6.png

我们发现只有少数几种的户型数量比较多,其余的都非常少,明显属于长尾分布类型(严重偏态),所以,考虑将800套一下的户型统统归为一类。

# 把低于八百套的房型设置为其他
drop_df2 = drop_df.copy()
for i in range(len(drop_df2['room_type'])):
    if drop_df2['room_type'].iloc[i] not in [u'2室2厅',u'2室1厅',u'3室2厅',u'1室1厅',u'4室2厅',u'3室1厅',u'1室0厅',u'1室2厅',u'2室0厅']:
        drop_df2['room_type'].iloc[i] = u'其他'
new_room_type_count = drop_df2.groupby(['room_type'])['name'].count()

figure = plt.figure(figsize=(15,9))
ax5 = plt.subplot(111)
rect5 = ax5.bar(np.arange(len(new_room_type_count)),new_room_type_count.values,width =0.4)
auto_tag(rect5)
auto_xticks(rect5,new_room_type_count.index)
plt.legend(rect5,[u'房源数量'],loc = 'upper right')
#每个地区的单位面积月租均价
Price_per_by_room = (drop_df2.groupby(['room_type'])['Price_average'].mean()).round(2)

#绘制每平米月租金折线图
ax6 = ax5.twinx()
x = [i for i in range(len(Price_per_by_room))]
y = Price_per_by_room.values
rect6 = ax6.plot(x,y,'mo-', label = 'right')
auto_tag(rect6,Price_per_by_room)
plt.legend(rect6,[u'每平米月租金'],loc = 'upper center')
ax5.set_title(u'户型分布情况')
7.png

从上图可以看出2室和3室的房源数量最多,考虑到舒适性和生活的便利性,同时根据租金情况来看,不妨选择2室1厅,2室2厅合租的房源性价比更高。

楼层的影响

#查看楼层分布情况
count_by_louceng = drop_df.groupby(['louceng'])['name'].count().sort_values(ascending = False)
figure = plt.figure(figsize = (5,5))
ax7 = plt.subplot(111)
rect7 = ax7.bar(np.arange(len(count_by_louceng)),count_by_louceng.values,width =0.4)
auto_tag(rect7)
auto_xticks(rect7,count_by_louceng.index)
ax7.set_title(u'楼层数量分布情况')
8.png
#观察各区的月租金箱形图
count_by_louceng_rent = drop_df.groupby(['louceng'])['price']
nn =[]
for group in count_by_louceng.index:
    v = count_by_louceng_rent.get_group(group).values
    nn.append(v)
fig = plt.figure(figsize = (5,5))
ax9 = plt.subplot(111)
rect9 = ax9.boxplot(nn,whis = 1)
#设置标签
ax9.set_xticklabels(count_by_louceng.index)
plt.yticks(range(0,20000,3000))
9.png

由上图可以看出低中高楼层对房屋租金的影响不是特别大,但是高层的房屋价格相对于低层的房子要稍微便宜一点,可能与通勤时间有关。如果不在意每天爬楼的通勤时间,选择高区或者是个不错的选择。

地铁及到地铁的距离的影响

上海地铁是一线城市中最发达的,所以如果能够在地铁附近租房对日常的出行都有很大的便利,所以地铁房的价格也必然增加。

#查看地铁分布情况
count_by_subway = drop_df.groupby(['subway'])['name'].count().sort_values(ascending = False)
Price_average_of_subway = (drop_df.groupby(['subway'])['Price_average'].mean()).round(2)

angles = np.linspace(0, 2 * np.pi, len(Price_average_of_subway), endpoint=False)
data = np.concatenate((Price_average_of_subway.values, [Price_average_of_subway.values[0]])) # 闭合
angles = np.concatenate((angles, [angles[0]])) # 闭合

fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(111, polar=True)# polar参数!!
ax.plot(angles, data, 'bo-', linewidth=2)# 画线
ax.set_thetagrids(angles * 180/np.pi, Price_average_of_subway.index)
ax.set_title(u'上海各地铁线附近房源租金雷达图')
ax.set_rlim(0,130)
ax.grid(True)
for i in range(len(Price_average_of_subway)):
    plt.text(angles[i]+0.01,data[i]+5,data[i])
plt.show()
10.png

4号线、10号线、13号线的房源价格最高,相对而言,非地铁房的价格较低,绝大多数都是低价房和少部分的高档别墅,这与我们的认知预测相符。我们单独的取房源最多的各区的地铁分布情况拿出来看:

j=0
for i in count_by_region.sort_values(ascending =False)[:4].index:
    j += 1
    #查看各区地铁分布情况
    count_by_subway1 = drop_df[drop_df['region']== i].groupby(['subway'])['name'].count().sort_values(ascending = False)
    Price_average_of_subway1 = (drop_df[drop_df['region']== i].groupby(['subway'])['Price_average'].mean()).round(2)
    angles = np.linspace(0, 2 * np.pi, len(Price_average_of_subway1), endpoint=False)
    data = np.concatenate((Price_average_of_subway1.values, [Price_average_of_subway1.values[0]])) # 闭合
    angles = np.concatenate((angles, [angles[0]])) # 闭合

    fig = plt.figure(figsize=(20,20))
    ax = fig.add_subplot(2,4,j, polar=True)# polar参数!!
    ax.plot(angles, data, 'bo-', linewidth=2)# 画线
    ax.set_thetagrids(angles * 180/np.pi, Price_average_of_subway1.index)
    ax.set_title(i+u'各地铁线附近房源租金雷达图')
    ax.set_rlim(0,150)
    ax.grid(True)
    for i in range(len(Price_average_of_subway1)):
        plt.text(angles[i]+0.01,data[i]+5,data[i])
11.png
12.png

由各区地铁雷达图可以看出不同区的地铁线路不同,价格也不一样,但是非地铁房的价格依然相对于地铁房的价格要便宜不少,如果公司离住的地方很近,没有地铁需求的话,可以找非地铁房比较划算。

#以浦东新区6号线为例,查看到地铁站距离对租金的影响
data_of_distance = drop_df[drop_df['region'] == u'浦东']
data_of_distance = data_of_distance[data_of_distance['subway'] == u'6号线']
dd = data_of_distance.sort_values(by = ['distance'])
#画散点图
fig = plt.figure(figsize = (10,9))
ax1 = fig.add_subplot(111)
ax1.scatter(dd['distance'].values,dd['Price_average'].values) 
plt.xlabel(u'到地铁站距离')
plt.ylabel(u'租金')
ax1.set_title(u'地铁站距离对租金影响图')
13.png

由上图可以看出到地铁站的距离多在350m-750m之间,且在此距离内租金也相对较高一点。

不同的宣传标题关键词的影响

#处理title字段
#抽取关键词
def key_words(text):
    key_words = jieba.analyse.extract_tags(text,topK = 20,withWeight = False,allowPOS=())
    return key_words

drop_df['key_words'] = drop_df['title'].apply(key_words)

#创建一个文本,将关键词列表全部写入该文本
def new_text(wordlist):
    f =open('D:/jupyter/wordlist_text.txt','a')
    for word in wordlist:
        f.writelines((word + u',').encode('utf-8'))
    f.close()
    
drop_df['key_words'].apply(new_text)

text = open('wordlist_text.txt','r').read()
text = unicode(text,encoding = 'utf-8') #必须将utf-8转码为unicode中间值才能生成词云
my_wordcloud = WordCloud(width = 800,height = 400,background_color= 'white').generate(text) #读入文本写入词云
fig = plt.figure(figsize =(10,8))
plt.imshow(my_wordcloud)
plt.axis('off')
plt.show()
14.png

从词云上可以看出,宣传标题很大程度上反映了租客们的需求和关注点,地铁沿线,交通便利,生活方便,光线充足,视野开阔等是大家比较关注的一些租房要素,同时改善,精致等也有不小的比例,这类房源的客户对象应该是工作几年后有了积蓄后的改善性租房。同时一链倾城的出现频率接近最高,应该是与链家网的“一链倾城,有爱有家”的宣传口号有关系。

分析结论

通过上面的分析,我们可以得到的结论有这些:
1、租房的房源主要分布在浦东新区和闵行、宝山等郊区,租金也相对城区便宜很多;
2、徐汇、长宁、静安等中心城区的租房价格仍高居不下;
3、户型多为2室1厅,2室2厅,3室两厅,比较适合居家常驻,可以选择2室,3室的合租相对更加便利些;
4、低中高楼层对房屋租金的影响不是特别大,但是高层的房屋价格相对于低层的房子要稍微便宜一点,所以如果不在意每天爬楼的通勤时间,选择高区或许是个不错的选择;
5、不同城区的地铁线路不同,租金价格也不一样,非地铁房的价格要更加便宜;
6、地铁房到地铁站的距离多为350m—750m之间,租金也相对高一点;
7、选择租房的时候不妨多实地看看,地铁沿线,交通便利,生活方便,光线充足,视野开阔都是很好的衡量点。

总而言之,大家可以根据公司的地点选择合适的区域进行租房,能租在公司附近是最优的选择,如果无法在公司附近租房且手头较紧,浦东和闵行等区或许是个不错的选择,同时地铁比较发达,交通也比较方便。希望大家都能租到自己合适的房子。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容