北京链家网租房信息的数据分析项目实战

本篇博客主要参考了《Python 数据分析与应用 :从数据获取到可视化》这本书,数据来源是通过爬虫爬取链家网的租房信息,可以参考我的另一篇博客python正则表达式爬取链家租房信息

数据读取

import pandas as pd 
import numpy as np

# 读取北京租房信息
file_path = open('D:/文件/python/python练习/11_网络爬虫/lianjiazufang.csv')
file_data = pd.read_csv(file_path)
file_data
地区 小区名称 户型 面积(㎡) 价格(元/月)
0 海淀 永定路85号院 2室1厅 南/北 2室1厅1卫 45 4500
1 朝阳 整租·华贸城 1室1厅 东南 1室1厅2卫 53 6800
2 丰台 整租·六里桥小区 2室1厅 南/北 2室1厅1卫 61 5500
3 朝阳 北花园小区 1室0厅 南 1室0厅1卫 52 4100
4 顺义 幸福东区 3室1厅 东南 3室1厅1卫 94 4300
5 朝阳 团结湖北五条 1室1厅 南 1室1厅1卫 40 5400
6 东城 整租·管村26号院 2室1厅 南/北 2室1厅1卫 69 5000
7 大兴 新凤小区 3室1厅 南/北 3室1厅1卫 95 2000
8 海淀 整租·北三环中路甲69号院 2室1厅 南/北 2室1厅1卫 59 6800
9 朝阳 整租·安贞西里 1室1厅 南 1室1厅1卫 42 5000
10 海淀 整租·月季园 3室1厅 东 3室1厅1卫 61 8600
11 朝阳 整租·电建南院 2室1厅 南/北 2室1厅1卫 69 5600
12 朝阳 整租·安贞西里 2室1厅 南/北 2室1厅1卫 65 6500
13 朝阳 整租·惠新里小区 2室1厅 南/北 2室1厅1卫 40 5500
14 昌平 整租·华龙苑中里 2室1厅 东/北 2室1厅1卫 53 5500
15 海淀 燕北园 3室1厅 南/北 3室1厅1卫 80 7500
16 大兴 兴海家园日苑 1室1厅 南/北 1室1厅1卫 65 4000
17 朝阳 整租·胜古南里 2室1厅 东南 2室1厅1卫 53 6300
18 顺义 金地未未来 2室1厅 西 2室1厅2卫 42 3500
19 朝阳 柏林爱乐二期 1室1厅 东北 1室1厅1卫 58 5500
20 丰台 整租·葛村西里 2室1厅 南/北 2室1厅1卫 52 4200
21 丰台 整租·角门东里 2室1厅 南 2室1厅1卫 60 5500
22 昌平 龙禧苑一区 3室1厅 南/北 3室1厅1卫 105 5999
23 海淀 车道沟南里 1室1厅 南 1室1厅1卫 15 2800
24 石景山 青年公寓 1室1厅 南 1室1厅1卫 45 3100
25 丰台 整租·中建一局北院 2室1厅 南 2室1厅1卫 78 4800
26 朝阳 整租·朝阳无限 1室1厅 南 1室1厅1卫 68 7300
27 朝阳 整租·花园闸小区 2室1厅 南/北 2室1厅1卫 57 4800
28 西城 百万庄1号院 2室1厅 南/北 2室1厅1卫 63 6500
29 顺义 整租·蓝星花园 1室0厅 西 1室0厅1卫 36 3300
... ... ... ... ... ...
2927 海淀 整租·双紫小区 2室1厅 南 2室1厅2卫 91 9000
2928 门头沟 整租·霁月园 2室1厅 南/北 2室1厅1卫 87 3900
2929 朝阳 整租·半岛国际公寓 2室1厅 南/北 2室1厅1卫 109 13000
2930 朝阳 地杰长安驿 1室0厅 西 1室0厅1卫 44 8000
2931 朝阳 整租·八里庄南里 1室1厅 南 1室1厅1卫 42 5300
2932 朝阳 整租·国际友谊花园 1室1厅 北 1室1厅1卫 86 8800
2933 昌平 整租·教育局宿舍 3室1厅 南/北 3室1厅1卫 60 3800
2934 朝阳 望京新城 2室1厅 西南 2室1厅1卫 106 9500
2935 丰台 整租·建国街一里 2室1厅 南/北 2室1厅1卫 60 4000
2936 海淀 整租·双榆树北里 2室1厅 南 2室1厅1卫 57 8800
2937 朝阳 北京像素南区 1房间 西南 1房间1卫 44 4400
2938 丰台 整租·西罗园南里 2室1厅 南/北 2室1厅1卫 74 5600
2939 昌平 整租·宁馨苑 2室1厅 南/北 2室1厅1卫 101 5000
2940 海淀 整租·半壁店六建宿舍 1室1厅 南 1室1厅1卫 41 4800
2941 海淀 整租·牡丹园东里 1室1厅 南 1室1厅1卫 40 6700
2942 海淀 整租·新科祥园 2室1厅 东南 2室1厅1卫 83 16200
2943 石景山 整租·西井小区一区 2室1厅 东 2室1厅1卫 50 4500
2944 朝阳 凤凰城三期 1室1厅 东/西 1室1厅1卫 79 13000
2945 西城 马甸南村 2室1厅 东北 2室1厅1卫 64 8500
2946 房山 整租·长阳国际城二区 2室1厅 南 2室1厅1卫 80 3900
2947 丰台 整租·卢沟桥南里 3室1厅 南/北 3室1厅1卫 74 4200
2948 通州 格兰晴天 3室1厅 南/北 3室1厅2卫 133 7000
2949 海淀 整租·航天社区 1室1厅 南 1室1厅1卫 44 7500
2950 通州 玉桥东路19号院 2室1厅 南/北 2室1厅1卫 90 3600
2951 通州 玉桥西里70号院 2室1厅 南/北 2室1厅1卫 89 3800
2952 大兴 整租·中建国际港 3室2厅 南/北 3室2厅2卫 123 7800
2953 通州 靓景明居 2室1厅 南/北 2室1厅1卫 69 4200
2954 顺义 华英园 2室1厅 南/北 2室1厅1卫 100 3900
2955 朝阳 整租·建国路100号 2室1厅 南 2室1厅1卫 61 8500
2956 大兴 整租·宏大南园 3室1厅 南/北 3室1厅2卫 143 7500

2957 rows × 5 columns

数据预处理

重复值处理

通过pandas中的duplicated()方法完成,只要有重复的数据就会映射为True。

# 检测重复数据

file_data.duplicated()
0       False
1       False
2       False
3       False
4       False
5       False
6       False
7       False
8       False
9       False
10      False
11      False
12      False
13      False
14      False
15      False
16      False
17      False
18      False
19      False
20      False
21      False
22      False
23      False
24      False
25      False
26      False
27      False
28      False
29      False
        ...  
2927    False
2928    False
2929    False
2930    False
2931    False
2932    False
2933    False
2934    False
2935    False
2936    False
2937    False
2938    False
2939    False
2940    False
2941    False
2942    False
2943    False
2944    False
2945    False
2946    False
2947    False
2948    False
2949    False
2950    False
2951    False
2952    False
2953    False
2954    False
2955    False
2956    False
Length: 2957, dtype: bool
# 删除重复数据,并对file_data重新赋值
file_data = file_data.drop_duplicates()

file_data.head()
地区 小区名称 户型 面积(㎡) 价格(元/月)
0 海淀 永定路85号院 2室1厅 南/北 2室1厅1卫 45 4500
1 朝阳 整租·华贸城 1室1厅 东南 1室1厅2卫 53 6800
2 丰台 整租·六里桥小区 2室1厅 南/北 2室1厅1卫 61 5500
3 朝阳 北花园小区 1室0厅 南 1室0厅1卫 52 4100
4 顺义 幸福东区 3室1厅 东南 3室1厅1卫 94 4300

空值处理

直接使用dropna()方法检测并删除缺失的数据

# 删除缺失数据,并对file_data重新赋值
file_data = file_data.dropna()
file_data.tail()
地区 小区名称 户型 面积(㎡) 价格(元/月)
2952 大兴 整租·中建国际港 3室2厅 南/北 3室2厅2卫 123 7800
2953 通州 靓景明居 2室1厅 南/北 2室1厅1卫 69 4200
2954 顺义 华英园 2室1厅 南/北 2室1厅1卫 100 3900
2955 朝阳 整租·建国路100号 2室1厅 南 2室1厅1卫 61 8500
2956 大兴 整租·宏大南园 3室1厅 南/北 3室1厅2卫 143 7500

数据转换类型

创建一个空数组

data_new = np.array([])

取出“面积”一列数据,将每个数据末尾的中文字符去除

data = file_data[‘面积(㎡)’].values
for i in data:
data_new = np.append(data_new,np.array(i[:-2]))

通过astype()方法将str类型转换为float64类型

data = data_new.astype(np.float64)

用新的数据替换

file_data.loc[:,‘面积(㎡)’]=data
file_data

在"户型"一列中,大部分数据显示的是“几室几厅几卫”,只有个别数据显示的是“几房间几
卫”,需要将“房间”替换成“室”,以保证数据的一致性。

# 获取“户型”一列数据
housetype_data = file_data['户型']
temp_list = []
# 通过replace()方法进行替换
for i in housetype_data:
    new_info = i.replace('房间','室')
    temp_list.append(new_info)
file_data.loc[:,'户型']=temp_list
file_data
地区 小区名称 户型 面积(㎡) 价格(元/月)
0 海淀 永定路85号院 2室1厅 南/北 2室1厅1卫 45 4500
1 朝阳 整租·华贸城 1室1厅 东南 1室1厅2卫 53 6800
2 丰台 整租·六里桥小区 2室1厅 南/北 2室1厅1卫 61 5500
3 朝阳 北花园小区 1室0厅 南 1室0厅1卫 52 4100
4 顺义 幸福东区 3室1厅 东南 3室1厅1卫 94 4300
5 朝阳 团结湖北五条 1室1厅 南 1室1厅1卫 40 5400
6 东城 整租·管村26号院 2室1厅 南/北 2室1厅1卫 69 5000
7 大兴 新凤小区 3室1厅 南/北 3室1厅1卫 95 2000
8 海淀 整租·北三环中路甲69号院 2室1厅 南/北 2室1厅1卫 59 6800
9 朝阳 整租·安贞西里 1室1厅 南 1室1厅1卫 42 5000
10 海淀 整租·月季园 3室1厅 东 3室1厅1卫 61 8600
11 朝阳 整租·电建南院 2室1厅 南/北 2室1厅1卫 69 5600
12 朝阳 整租·安贞西里 2室1厅 南/北 2室1厅1卫 65 6500
13 朝阳 整租·惠新里小区 2室1厅 南/北 2室1厅1卫 40 5500
14 昌平 整租·华龙苑中里 2室1厅 东/北 2室1厅1卫 53 5500
15 海淀 燕北园 3室1厅 南/北 3室1厅1卫 80 7500
16 大兴 兴海家园日苑 1室1厅 南/北 1室1厅1卫 65 4000
17 朝阳 整租·胜古南里 2室1厅 东南 2室1厅1卫 53 6300
18 顺义 金地未未来 2室1厅 西 2室1厅2卫 42 3500
19 朝阳 柏林爱乐二期 1室1厅 东北 1室1厅1卫 58 5500
20 丰台 整租·葛村西里 2室1厅 南/北 2室1厅1卫 52 4200
21 丰台 整租·角门东里 2室1厅 南 2室1厅1卫 60 5500
22 昌平 龙禧苑一区 3室1厅 南/北 3室1厅1卫 105 5999
23 海淀 车道沟南里 1室1厅 南 1室1厅1卫 15 2800
24 石景山 青年公寓 1室1厅 南 1室1厅1卫 45 3100
25 丰台 整租·中建一局北院 2室1厅 南 2室1厅1卫 78 4800
26 朝阳 整租·朝阳无限 1室1厅 南 1室1厅1卫 68 7300
27 朝阳 整租·花园闸小区 2室1厅 南/北 2室1厅1卫 57 4800
28 西城 百万庄1号院 2室1厅 南/北 2室1厅1卫 63 6500
29 顺义 整租·蓝星花园 1室0厅 西 1室0厅1卫 36 3300
... ... ... ... ... ...
2927 海淀 整租·双紫小区 2室1厅 南 2室1厅2卫 91 9000
2928 门头沟 整租·霁月园 2室1厅 南/北 2室1厅1卫 87 3900
2929 朝阳 整租·半岛国际公寓 2室1厅 南/北 2室1厅1卫 109 13000
2930 朝阳 地杰长安驿 1室0厅 西 1室0厅1卫 44 8000
2931 朝阳 整租·八里庄南里 1室1厅 南 1室1厅1卫 42 5300
2932 朝阳 整租·国际友谊花园 1室1厅 北 1室1厅1卫 86 8800
2933 昌平 整租·教育局宿舍 3室1厅 南/北 3室1厅1卫 60 3800
2934 朝阳 望京新城 2室1厅 西南 2室1厅1卫 106 9500
2935 丰台 整租·建国街一里 2室1厅 南/北 2室1厅1卫 60 4000
2936 海淀 整租·双榆树北里 2室1厅 南 2室1厅1卫 57 8800
2937 朝阳 北京像素南区 1房间 西南 1室1卫 44 4400
2938 丰台 整租·西罗园南里 2室1厅 南/北 2室1厅1卫 74 5600
2939 昌平 整租·宁馨苑 2室1厅 南/北 2室1厅1卫 101 5000
2940 海淀 整租·半壁店六建宿舍 1室1厅 南 1室1厅1卫 41 4800
2941 海淀 整租·牡丹园东里 1室1厅 南 1室1厅1卫 40 6700
2942 海淀 整租·新科祥园 2室1厅 东南 2室1厅1卫 83 16200
2943 石景山 整租·西井小区一区 2室1厅 东 2室1厅1卫 50 4500
2944 朝阳 凤凰城三期 1室1厅 东/西 1室1厅1卫 79 13000
2945 西城 马甸南村 2室1厅 东北 2室1厅1卫 64 8500
2946 房山 整租·长阳国际城二区 2室1厅 南 2室1厅1卫 80 3900
2947 丰台 整租·卢沟桥南里 3室1厅 南/北 3室1厅1卫 74 4200
2948 通州 格兰晴天 3室1厅 南/北 3室1厅2卫 133 7000
2949 海淀 整租·航天社区 1室1厅 南 1室1厅1卫 44 7500
2950 通州 玉桥东路19号院 2室1厅 南/北 2室1厅1卫 90 3600
2951 通州 玉桥西里70号院 2室1厅 南/北 2室1厅1卫 89 3800
2952 大兴 整租·中建国际港 3室2厅 南/北 3室2厅2卫 123 7800
2953 通州 靓景明居 2室1厅 南/北 2室1厅1卫 69 4200
2954 顺义 华英园 2室1厅 南/北 2室1厅1卫 100 3900
2955 朝阳 整租·建国路100号 2室1厅 南 2室1厅1卫 61 8500
2956 大兴 整租·宏大南园 3室1厅 南/北 3室1厅2卫 143 7500

2957 rows × 5 columns

图表分析

房源数量,位置分布分析

# 创建一个DataFrame 对象,该对象只有两列数据:区域和数量
new_df = pd.DataFrame({'区域':file_data['地区'].unique(),
                      
                        '数量':[0]*14 })

new_df
区域 数量
0 海淀 0
1 朝阳 0
2 丰台 0
3 顺义 0
4 东城 0
5 大兴 0
6 昌平 0
7 石景山 0
8 西城 0
9 通州 0
10 亦庄开发区 0
11 门头沟 0
12 房山 0
13 怀柔 0

接下来,通过pandas的groupby()方法将file_data对象按照“区域”一列进行分组,并利用count()方法统计每个分组的数量

groupby_area = file_data.groupby(by='地区').count()


new_df['数量']=groupby_area.values

new_df
区域 数量
0 海淀 154
1 朝阳 340
2 丰台 29
3 顺义 142
4 东城 1
5 大兴 59
6 昌平 192
7 石景山 905
8 西城 463
9 通州 101
10 亦庄开发区 169
11 门头沟 226
12 房山 44
13 怀柔 132
# 按数量一列从大到小排列

new_df.sort_values(by=['数量'],ascending=False)


区域 数量
7 石景山 905
8 西城 463
1 朝阳 340
11 门头沟 226
6 昌平 192
10 亦庄开发区 169
0 海淀 154
3 顺义 142
13 怀柔 132
9 通州 101
5 大兴 59
12 房山 44
2 丰台 29
4 东城 1

户型数量分析

# 定义函数,用于计算各户型的数量
def all_house(arr):
    arr = np.array(arr)
    key = np.unique(arr)
    result = {}
    for k in key:
        mask = (arr==k)
        arr_new=arr[mask]
        v=arr_new.size
        result[k]=v
    return result

# 获取用户数据
house_array = file_data['户型']
house_info = all_house(house_array)
house_info
{'14室3厅5卫': 1,
 '1室0厅0卫': 7,
 '1室0厅1卫': 205,
 '1室0厅2卫': 1,
 '1室1卫': 12,
 '1室1厅0卫': 1,
 '1室1厅1卫': 752,
 '1室1厅2卫': 14,
 '1室2厅1卫': 12,
 '1室2厅2卫': 1,
 '2室0卫': 2,
 '2室0厅0卫': 1,
 '2室0厅1卫': 14,
 '2室1卫': 10,
 '2室1厅1卫': 1285,
 '2室1厅2卫': 76,
 '2室1厅3卫': 1,
 '2室2卫': 1,
 '2室2厅1卫': 85,
 '2室2厅2卫': 22,
 '3室0厅1卫': 4,
 '3室1卫': 2,
 '3室1厅1卫': 193,
 '3室1厅2卫': 85,
 '3室1厅3卫': 1,
 '3室2卫': 1,
 '3室2厅1卫': 21,
 '3室2厅2卫': 90,
 '3室2厅3卫': 5,
 '3室3厅2卫': 1,
 '4室1厅1卫': 5,
 '4室1厅2卫': 8,
 '4室1厅3卫': 2,
 '4室2厅2卫': 13,
 '4室2厅3卫': 10,
 '4室3厅2卫': 1,
 '5室1厅1卫': 1,
 '5室1厅2卫': 1,
 '5室1厅3卫': 1,
 '5室2厅3卫': 2,
 '5室2厅5卫': 1,
 '5室3厅4卫': 1,
 '5室3厅5卫': 1,
 '6室2厅3卫': 1,
 '6室2厅4卫': 1,
 '6室2厅5卫': 1,
 '6室3厅3卫': 1}

使用字典推导式将用户大于50的元素筛选出来,并将筛选后的结果转换成DataFrame对象

# 使用字典推导式
house_type = dict((key,value) for key,value in house_info.items() if value > 50)
show_houses = pd.DataFrame({'户型':[x for x in house_type.keys()],'数量':[x for x in house_type.values()]})

show_houses
户型 数量
0 1室0厅1卫 205
1 1室1厅1卫 752
2 2室1厅1卫 1285
3 2室1厅2卫 76
4 2室2厅1卫 85
5 3室1厅1卫 193
6 3室1厅2卫 85
7 3室2厅2卫 90

为了能够更加直观的看到户型数量之间的差异,我们可以使用条形图进行展示,其中,条形图的纵坐标代表户型种类,横坐标代表户型数量

import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus']=False
house_type=show_houses['户型']
house_type_num=show_houses['数量']
plt.barh(range(8),house_type_num,height=0.7,color='steelblue',alpha=0.8)
plt.yticks(range(8),house_type)
plt.xlim(0,1500)
plt.xlabel('数量')
plt.ylabel('户型种类')
plt.title('北京地区各户型房屋数量')
for x, y in enumerate(house_type_num):
    plt.text(y+0.2,x-0.1,'%s' % y)
plt.show()

北京链家网租房信息的数据分析项目实战_第1张图片

通过图形可以清楚的知道整个租房市场中户型比较多的是2室1厅1卫,1室1厅1卫,1室0厅1卫,3室1厅1卫,其中2室1厅1卫是最多的

平均租金分析

# 新建一个DataFrame对象,设置房租总金额和总面积初始值为0
df_all = pd.DataFrame({'区域':file_data['地区'].unique(),'房租总金额':[0]*14,'总面积(㎡)':[0]*14})
df_all
区域 房租总金额 总面积(㎡)
0 海淀 0 0
1 朝阳 0 0
2 丰台 0 0
3 顺义 0 0
4 东城 0 0
5 大兴 0 0
6 昌平 0 0
7 石景山 0 0
8 西城 0 0
9 通州 0 0
10 亦庄开发区 0 0
11 门头沟 0 0
12 房山 0 0
13 怀柔 0 0
# 求总金额和总面积
sum_price = file_data['价格(元/月)'].groupby(file_data['地区']).sum()
sum_area = file_data['面积(㎡)'].groupby(file_data['地区']).sum()
df_all['房租总金额']=sum_price.values
df_all['总面积(㎡)']=sum_area.values
df_all
区域 房租总金额 总面积(㎡)
0 海淀 1320150 10232
1 朝阳 1861750 23241
2 丰台 152000 2704
3 顺义 603450 11722
4 东城 13000 348
5 大兴 178600 4078
6 昌平 1047329 16766
7 石景山 7829700 68655
8 西城 3873500 33640
9 通州 523900 6764
10 亦庄开发区 1537100 11207
11 门头沟 982800 17723
12 房山 136350 3048
13 怀柔 578050 10967
# 计算各区域每平方米房租价格,并保留2位小数
df_all['每平方米租金(元)']=round(df_all['房租总金额']/df_all['总面积(㎡)'],2)

df_all
区域 房租总金额 总面积(㎡) 每平方米租金(元)
0 海淀 1320150 10232 129.02
1 朝阳 1861750 23241 80.11
2 丰台 152000 2704 56.21
3 顺义 603450 11722 51.48
4 东城 13000 348 37.36
5 大兴 178600 4078 43.80
6 昌平 1047329 16766 62.47
7 石景山 7829700 68655 114.04
8 西城 3873500 33640 115.15
9 通州 523900 6764 77.45
10 亦庄开发区 1537100 11207 137.16
11 门头沟 982800 17723 55.45
12 房山 136350 3048 44.73
13 怀柔 578050 10967 52.71
# 合并df_all与new_df

df_merge = pd.merge(new_df,df_all)

df_merge
区域 数量 房租总金额 总面积(㎡) 每平方米租金(元)
0 海淀 154 1320150 10232 129.02
1 朝阳 340 1861750 23241 80.11
2 丰台 29 152000 2704 56.21
3 顺义 142 603450 11722 51.48
4 东城 1 13000 348 37.36
5 大兴 59 178600 4078 43.80
6 昌平 192 1047329 16766 62.47
7 石景山 905 7829700 68655 114.04
8 西城 463 3873500 33640 115.15
9 通州 101 523900 6764 77.45
10 亦庄开发区 169 1537100 11207 137.16
11 门头沟 226 982800 17723 55.45
12 房山 44 136350 3048 44.73
13 怀柔 132 578050 10967 52.71
import matplotlib.ticker as mtick
from matplotlib.font_manager import FontProperties

num = df_merge['数量']                  # 数量
price = df_merge['每平方米租金(元)']    # 价格

l = [i for i in range(14)]
plt.rcParams['font.sans-serif']=['SimHei']
lx = df_merge['区域']
fig = plt.figure()
axl = fig.add_subplot(111)
axl.plot(l, price,'or-',label = '价格')
for i,(_x,_y) in enumerate(zip(l,price)):
    plt.text(_x,_y,price[i],color='black',fontsize=10)
    axl.set_ylim([0,200])
    axl.set_ylabel('价格')
    plt.legend(prop={'family':'SimHei','size':8},loc='upper left')
    ax2 = axl.twinx()
    plt.bar(l,num,alpha=0.3,color = 'green',label = '数量')
    ax2.set_ylabel('数量')
    ax2.set_ylim([0,2000])
    plt.legend(prop={'family':'SimHei','size':8},loc="upper right")
    plt.xticks(l,lx)
plt.show()

北京链家网租房信息的数据分析项目实战_第2张图片

你可能感兴趣的:(python数据分析)