【数据可视化-06】--- 北京某平台二手房可视化数据分析
The article presents an analysis of Beijing's second-hand house data, focusing on data cleaning, feature engineering, and visualization to explore market characteristics. The study aims to understand price patterns and distribution by examining factors such as area, price per square meter, number of rooms, floor, building type, and location.
Data cleaning involved handling missing values and outliers across 15 key fields. Outliers were identified using techniques like removing specified columns and filtering abnormal values based on domain knowledge. For example, abnormal floors were removed from the dataset.
Feature engineering included converting categorical variables like "area" into numerical format and replacing non-standard room types with a standard value (e.g., "room" to "room"). The analysis also addressed spatial distribution by categorizing areas into urban core, city ring road extension zone, and outer ring road extension zone.
Visualization techniques revealed significant regional differences in housing prices and availability. Areas like Haidian exhibited higher concentrations of second-hand houses compared to other regions such as Daxingguo District. Price distributions showed a right-skewed pattern with a median price of 609 ten thousand yuan.
The study highlighted that higher-priced houses tended to be located in central areas with more rooms or floors. Additionally, certain neighborhoods had over 15 instances of house sales within the past year.
Key conclusions emphasized the importance of data visualization in understanding market dynamics and provided insights for both homebuyers and investors in making informed decisions.
博主个人简历中记载了曾在某智慧城市相关企业的算法岗位历任要职。现任职于美国市场的一家物流公司高级算法工程师岗位,在人工智能领域深耕多年,并熟练掌握Python语言及其相关技术应用。其专业能力不仅体现在数据挖掘方面(如:...),还涵盖了软件可视化开发及机器学习等前沿技术研究工作。博主已获得多项与人工智能相关的专利,并多次在人工智能相关竞赛中取得优异成绩。作为人工智能领域的活跃贡献者,在该领域持续输出高质量的技术文章与实践案例分享,并提供包括但不限于AI技术咨询、项目开发及定制化解决方案的服务方案。如需进一步了解或合作交流,请访问我的个人VX名片(ID:xf982831907)获取更多信息。
💬 博主粉丝群介绍:① 群体中分布着初中生、高中生、本科生、研究生以及博士生等不同学历层次的学生,他们可以通过交流互动共同进步并解决学习上的困惑。② 群体中常有来自网络热榜排名前十的活跃用户以及无数万粉级的大佬级人物光临,在此分享写作技巧、参赛经验以及提升粉丝量的方法论。③ 此外还有许多职场精英和大厂大佬在线分享技术见解、面试策略以及职业发展经验。④ 入群即送价值一份的写作秘籍,并助力 members 从写作新手逐步成长为优秀的创作者型人才。⑤ 进群还能获得专业的评论防封脚本,并享受真实的活跃粉丝资源以提升文章质量与曝光度。有意向者可加文末联系方式并注明个人昵称即可入群参与交流共同进步。

一、引言
本案例研究采用来自北京某平台的二手房数据集作为分析基础,并结合数据可视化技术进行深入探究。经过系统性地进行数据清洗处理(这一过程至关重要),我们能够对房屋价格、面积、是否有电梯等关键指标进行详细展示。通过该分析方法能够深入挖掘北京二手房市场的运行规律及其发展趋势,并为购房者和投资者提供具有参考价值的决策依据。
为了达成这一目标, 我们采用了Python编程语言及其相关的数据分析库, 其中包含了pandas matplotlib seaborn以及pyecharts等工具. 这些强大的工具集提供了丰富的功能与操作能力 在处理数据时能帮助我们完成分析与可视化任务.
二、数据探索和清冼
进行数据探索和清冼的目的主要是因为数据来源并不是官方的,数据中往往存在一些异常情况,这些异常的情况会导致我们分析的结果出现大量的偏差,所以我们需要对爬取的北京二手房数据进行探索的清冼,数据集下载地址:<>
废话不多说直接上代码:
- 1、导入数据探索清冼需要的库
import pandas as pd
- 2、导入数据进行数据整体的探索
data = pd.read_csv("二手房数据.csv",encoding = 'gb18030')
#查看数据的维度
data.shape
#打印数据的前5行
data.head()

data.info()

从数据的整体情况来看, 我们观察到"11 Unnamed"列为均为空值, 而Id字段在后续分析中并未被使用, 因此建议删除这两项. 同时, 观察到该电梯字段存在较多缺失, 具体数据显示该字段共有8255条缺失记录, 并建议对这些记录进行清理处理.
3、对数据中的字段进行层次化分析
在后续阶段的分析过程中,主要会对数据中的某些字段进行可视化展示,并需留意不同维度下是否存在异常值(不应出现的情况)。
3.1 市区字段分析
data['市区'].value_counts()

在'市区列'字段中包含少量离群数据项[15, '有电梯', '京师吉地']。这些离群数据点的数量极少,不会对当前分析产生显著影响,建议直接移除这些记录
- 3.2 户型字段分析
data['户型'].unique()

从实验结果来看,在应用unique()函数时,则会生成一系列去重后的数据集。这些结果表明,在后续的数据处理阶段中,则要求将房间一词替换为室,并需清理那些不属于常规户型类别的描述项。具体来说,则涉及如下几种特殊类别:如叠拼别墅、带电梯 buildings以及京师吉地等户型列中的异常值。
- 3.3 其它字段的分析
# 小区
len(data['小区'].unique())
#电梯
data['电梯'].value_counts()
#朝向
data['朝向'].unique()
#楼层
data['楼层'].unique()
#装修情况
data['装修情况'].value_counts()
#面积
data['面积(㎡)'].unique()
#年份
data['年份'].unique()
分析:
- 当前小区列的字段数量过多,在本次分析中无需处理此字段;
- 电梯列存在较高的缺失比例(即缺失值占较大比重),后续将所有非'有电梯'或'无电梯'的记录标记为'未知';
- 对于朝向列中的特定异常记录['97', '有电梯', '京师吉地']及其对应行次进行剔除;
- 在楼层列中发现并剔除包含['490', '房山', '精装', '朝阳', '有电梯', '京师吉地']等异常信息的行;
- 对装修情况列中的['无电梯', '2013', '丽水嘉园', '长阳国际城三区', '有电梯', '京师吉地']等异常数据进行清理;
- 在年份列中识别并剔除包含['1.01E+11','其他','精装','西南','22','有电梯','京师吉地']等不规范数据的行;
- 对面积(㎡)列中的含有中文字符的内容进行过滤;
- 在价格(万元)列中发现并剔除与'光明西里'相关的异常数据。
- 4、编写最终的清冼代码
根据上面的分析,编写对应的代码如下
# clean步骤
# 删除指定的列 ['Unnamed: 11', 'Id']
data = data.drop(['Unnamed: 11', 'Id'], axis=1)
def remove_outlies(data,col_name='楼层',to_remove = ['490', '房山']):
mask = data[col_name].isin(to_remove)
data = data[~mask]
return data
# 市区列中异常值清冼
data = remove_outlies(data,'市区',['15', '有电梯', '京师吉地'])
# 电梯列中的数据清冼
data['电梯'] = data['电梯'].apply(lambda x:x if (x=='有电梯' or x=='无电梯') else '未知')
# 户型列中的数据清冼
data['户型'] = data['户型'].apply(lambda x:x.replace("房间",'室'))
data = remove_outlies(data,'户型',['叠拼别墅','有电梯', '京师吉地'])
# 朝向列中的数据清冼
data = remove_outlies(data,'朝向',['97','有电梯','京师吉地'])
# 楼层列中的数据清冼
data = remove_outlies(data,'楼层',['490', '房山', '精装', '朝阳', '有电梯', '京师吉地'] )
# 装修情况列中的数据清冼
data = remove_outlies(data,'装修情况',['无电梯','2013','丽水嘉园','长阳国际城三区','有电梯','京师吉地'])
# 年份列中的数据清冼
data = remove_outlies(data,'年份',['1.01E+11','其他','精装', '西南','22','有电梯', '京师吉地'])
# 面积(㎡)列中的数据清冼
def contains_chinese(s):
if isinstance(s, str):
return any('\u4e00' <= c <= '\u9fff' for c in s)
return False
mask = data['面积(㎡)'].apply(contains_chinese)
data = data[~mask]
data = remove_outlies(data,'价格(万元)',['光明西里'])
对清洗后的数据进行保存以便后续分析无需再次对清洗后数据进行处理清洗后数据的下载链接为<>并使用pandas库中的to_csv方法将清理好的文件存储到本地路径下具体命令如下:
data.to_csv('clean_data.csv', index=False, encoding='utf-8-sig')
三、数据分析和可视化
在本节中,请详细阐述您对数据进行分析与可视化所采取的具体步骤。请呈现关键图表与图形,并对它们所反映的内涵及发现进行深入解析。
加载绘图需要的库:
import pandas as pd
from pyecharts.charts import Map
from pyecharts.charts import Bar
from pyecharts.charts import Line
from pyecharts.charts import Grid
from pyecharts.charts import Pie
from pyecharts.charts import Scatter
from pyecharts import options as opts
from pyecharts.globals import ThemeType
from pyecharts.charts import Geo
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 指定默认字体:解决plot不能显示中文问题
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
导入清冼后的数据:
data = pd.read_csv(‘clean_data.csv’)
data.describe()

图中呈现了北京市二手房的相关统计数据信息。其中包含有"总价的平均值"为609万元,"时间维度"上的数据集中在2001年,"建筑层数"主要集中在12-13层区间,"房屋面积"的均值为99平方米左右。此外,该数据集还提供了包括标准差、最小值、四分位数等在内的多个统计指标数值。以下从几个方面展开数据可视化展示:
- 1)各区二手房数量条形图 ,获取数据中各区信息和对应区的房屋数量,绘制条形图
region_list = data['市区'].value_counts().index.tolist()
house_count_list = data['市区'].value_counts().values.tolist()
c = Bar(init_opts=opts.InitOpts(theme=ThemeType.CHALK))
c.add_xaxis(region_list)
c.add_yaxis("北京市", house_count_list)
c.set_global_opts(title_opts=opts.TitleOpts(title="北京各区二手房数量柱状图", subtitle=""),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(interval=0)))
# c.render("武汉各区二手房数量柱状图.html")
c.render_notebook()

2. **北京各个城区二手房价格地图分布**
zone_median = data.groupby(['市区'])['价格(万元)'].median()
c = (
Geo()
.add_schema(maptype='北京',itemstyle_opts=opts.ItemStyleOpts(color='#A60B63',border_color='#FFFF22'))
.add(
"",
[list(z) for z in zip(zone_median.keys().tolist(),zone_median.tolist())]
)
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
visualmap_opts=opts.VisualMapOpts(min_=280,max_=720),
title_opts=opts.TitleOpts(title="北京各个城区二手房平均价格(万元)", subtitle=""),
)
)
c.render_notebook()

- 各区二手房单价箱型图
收集各区二手房的名称数据及其对应的市场价格数据...用于生成箱型图。
统计各个区二手房单价信息
unit_price_list = []
for region in region_list:
unit_price_list.append(data.loc[data['市区'] == region, '价格(万元)'].values.tolist())
# 绘制箱型图
from pyecharts.charts import Boxplot
c = Boxplot(init_opts=opts.InitOpts(theme=ThemeType.CHALK))
c.add_xaxis(region_list)
c.add_yaxis("北京市", c.prepare_data(unit_price_list))
c.set_global_opts(title_opts=opts.TitleOpts(title="北京各区二手房总价箱型图"),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(interval=0)))
# c.render("boxplot_base.html")
c.render_notebook()

4. **二手房面积分布与价格关系图**
f, [ax1,ax2] = plt.subplots(1, 2, figsize=(16, 6))
# 房屋面积
sns.distplot(data['面积(㎡)'], ax=ax1, color='r')
sns.kdeplot(data['面积(㎡)'], shade=True, ax=ax1)
ax1.set_xlabel('面积')
# 房屋面积和价格的关系
sns.regplot(x='面积(㎡)', y='价格(万元)', data=data, ax=ax2)
ax2.set_xlabel('面积')
ax2.set_ylabel('总价')
plt.show()

5. **房屋朝向饼状图**
d = data.groupby('朝向')
direction = d.count()['小区']
direction

from pyecharts.charts import Pie
c = (
Pie()
.add(
"",
[list(z) for z in zip(direction.keys().tolist(),direction.values.tolist())],
radius=["30%", "75%"],
)
.set_global_opts(
title_opts=opts.TitleOpts(title="房屋朝向比"),
legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),
)
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)"))
)
c.render_notebook()

- 6) 各户型横向条形图
series = data['户型'].value_counts()
series.sort_index(ascending=False, inplace=True)
house_type_list = series.index.tolist()
count_list = series.values.tolist()
c = Bar(init_opts=opts.InitOpts(theme=ThemeType.CHALK))
c.add_xaxis(house_type_list)
c.add_yaxis("北京市", count_list)
c.reversal_axis()
c.set_series_opts(label_opts=opts.LabelOpts(position="right"))
c.set_global_opts(title_opts=opts.TitleOpts(title="北京二手房各户型横向条形图"),
datazoom_opts=[opts.DataZoomOpts(yaxis_index=0, type_="slider", orient="vertical")],)
#c.render("北京二手房各户型横向条形图.html")
c.render_notebook()

7. **房屋装修程度饼状图**
decoration_list = data['装修情况'].value_counts().index.tolist()
count_list = data['装修情况'].value_counts().values.tolist()
from pyecharts.charts import Pie
c = Pie(init_opts=opts.InitOpts(theme=ThemeType.CHALK))
c.add(series_name="房屋装修",
data_pair=[list(z) for z in zip(decoration_list, count_list)],
rosetype="radius",
radius="55%",
center=["50%", "50%"],
label_opts=opts.LabelOpts(is_show=False, position="center"))
c.set_global_opts(title_opts=opts.TitleOpts(
title="北京二手房房屋装修饼状图",
pos_left="center",
pos_top="20",
title_textstyle_opts=opts.TextStyleOpts(color="#fff")),
legend_opts=opts.LegendOpts(is_show=False))
c.set_series_opts(tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
label_opts=opts.LabelOpts(color="rgba(255, 255, 255, 255)"))
# c.render("customized_pie.html")
c.render_notebook()

8. **房屋面积分布柱状图**
area_level = [0, 50, 100, 150, 200, 250, 300, 350, 400, 1500]
label_level = ['50-100','100-150','150-200','200-250','250-300','300-350','350-400','400-450']
p1 = pd.cut(data['面积(㎡)'],area_level,label_level)
p2 = p1.value_counts()
p3 = p2.values.tolist()
p3
[13647, 5808, 1675, 1561, 541, 217, 93, 54, 53]
c = (
Bar()
.add_xaxis(label_level)
.add_yaxis("面积(㎡)",p3,color="#7944B7")
.reversal_axis()
.set_series_opts(
label_opts=opts.LabelOpts(position='right')
)
.set_global_opts(
title_opts=opts.TitleOpts(title="房屋面积分布柱状图"),
xaxis_opts=opts.AxisOpts(name='数量'),
yaxis_opts=opts.AxisOpts(name='面积(㎡)')
)
)
c.render_notebook()

9. **楼层的分布**
sns.distplot(data['楼层'],color='r')

10. **北京市二手房有无电梯的关系(柱状图)和有无电梯和房价的关系(折线图)**
df = data[data['电梯']!='未知']
sns.barplot(x="市区", y="价格(万元)", hue="电梯", data=df)

sns.lineplot(x=“市区”, y=“价格(万元)”, hue=“电梯”, data=df)

11. **出售房数大于15间且房价均值Top10的小区**
df = data['小区'].value_counts().reset_index() #data['小区']value_counts的结果转成dataframe
df1 = data.groupby(['小区'])['价格(万元)'].mean().reset_index()
df = df.merge(df1,on=['小区'],how='left')
# 筛选出计数大于15的小区
filtered_counts = df[df['count'] >= 15]
sorted_counts = filtered_counts.sort_values(by='价格(万元)',ascending=False)[:10]
sorted_counts

sns.barplot(x=‘小区’,y=‘价格(万元)’,data=sorted_counts)

本文完整代码下载地址:<>
总结: 在对北漂人聚集地二手住房数据进行可视化呈现时,基于上述分析结果可得如下结论.
北京二手房市场的价格呈现明显的分布规律,在不同价位区间内,房源数量与价格水平表现出一定的差异性。
在北京市二手房市场中,房屋面积的分布规律较为明显.就不同尺寸范围而言,在同一区域内的房源数量与对应的面积大小均表现出明显的区别.
二手房在北京市各区域的分布不够均衡,在这些重点区域内房源供应量较大,并且它们的售价普遍偏高。
这些分析结果不仅呈现了市场动态信息,并且提供了可供参考的数据依据。它们不仅能够帮助购房者更深入地认识当前房地产市场的运行机制,并且能够助力其做出更加明智的购房选择。对于投资者而言,则可以通过这一系列数据洞察能够更好地把握市场动向及投资机遇的相关信息。
需要注意的是,在本文的研究过程中,默认假设所有分析均基于某特定平台提供的二手房数据进行。这种研究方法不可避免地存在一定的局限性或不足,在实际应用时应当结合更多变量进行综合考量。例如,在实际购房和投资决策过程中,除了地理位置因素外还需要关注房屋的质量状况、所在区域的交通便利程度以及周边配套设施等多方面的指标信息。
运用数据可视化的方法能够帮助我们更加直观地认识二手房市场的具体情况,并为其提供更为全面的信息支持。本文旨在通过对相关数据进行深入分析所得到的结果,并期望这些结果能够对读者产生启发,在购房决策或投资过程中提供一定的参考价值。
