
简介本资源是一套完整的Python数据分析实战项目面向计算机、统计学或房地产相关专业的本科生及自学开发者聚焦南京二手房市场数据采集、清洗、可视化与聚类建模全流程适用于毕业设计、课程大作业或数据分析能力进阶训练。压缩包共157个文件40.04MB包含18个核心Python脚本爬虫、清洗、绘图、聚类、18个CSV数据文件含原始与清洗后多版本、65张可视化图表PNG、15个HTML交互地图页面集成高德JS API、11个JS前端支持文件及1份完整答辩用PPT文档。已有997人学习下载内容覆盖RequestsBeautifulSoup网络爬虫、Pandas数据清洗、Matplotlib/Seaborn可视化、KMeans聚类算法实现与地理热力图呈现等关键技术点所有代码可直接运行数据字段明确分析逻辑清晰附带多阶段中间结果文件便于调试与复现。1. 项目缘起从数据到洞察一次完整的二手房分析实战最近在整理本地房产数据时我手头正好有一批南京的二手房挂牌信息。这些数据躺在Excel表格里密密麻麻的数字和地址除了能看出总价和单价很难直观地感受到市场的全貌。比如哪个区的房源最集中不同区域的单价差异到底有多大总价和面积的关系是怎样的这些问题单看原始数据表格效率很低。作为一个习惯用Python解决实际问题的开发者我决定动手把这些数据“可视化”让它自己“说话”。这个项目就是一次从原始数据清洗、到分析、再到最终生成可视化图表和汇报PPT的完整流程实践。它不仅是一堆代码更是一套可复用的方法论适用于任何有类似结构化数据的分析场景。无论你是数据分析的初学者想通过一个实战项目练手还是业务人员希望掌握用Python快速洞察数据的能力这篇内容都能给你提供一条清晰的路径。我会把核心思路、关键代码、踩过的坑以及最终的成果包括源码和PPT模板都梳理出来你可以直接拿去换成你自己的数据跑一遍。2. 数据获取与预处理清洗是分析的第一步任何数据分析项目数据质量决定了天花板的高度。我们拿到的原始数据往往存在缺失、重复、格式不一致等问题直接进行分析会导致结果失真。2.1 数据来源与字段理解我使用的数据包含了南京各个行政区的二手房挂牌信息典型字段包括区域如鼓楼、建邺、秦淮、玄武等。小区名称房源所在的具体小区。户型如“3室2厅”、“2室1厅”等字符串。面积单位为平方米通常是浮点数。朝向如“南”、“南北通透”等。装修情况如“精装”、“简装”、“毛坯”。楼层信息包含楼层和总楼层如“中楼层/共6层”。建筑年代房屋的建成年份。总价单位为万元。单价单位为元/平方米。这些数据可能来自公开的房产信息平台通过爬虫获取也可能是公司内部的数据集。原始数据通常以CSV或Excel格式存储。2.2 使用Pandas进行数据清洗清洗工作主要借助pandas库完成这是Python数据分析的基石。import pandas as pd import numpy as np # 1. 读取数据 df pd.read_csv(nanjing_second_hand.csv, encodingutf-8) # 根据实际编码调整 # 2. 初步查看数据 print(df.head()) print(df.info()) print(df.describe())df.info()可以帮助我们快速查看各字段的非空值数量、数据类型这是发现数据缺失问题的第一步。df.describe()则针对数值型字段如面积、总价、单价给出统计摘要均值、标准差、分位数等有助于发现异常值。接下来是具体的清洗步骤处理缺失值对于关键数值字段如面积、总价如果缺失比例不高可以考虑删除该行记录。如果缺失比例较高或者字段重要性一般可以根据业务逻辑进行填充。例如单价缺失可以用总价/面积计算得出装修情况缺失可以填充为“未知”。# 删除关键字段如总价、面积为空的记录 df_cleaned df.dropna(subset[总价, 面积]) # 或者用中位数填充单价字段的缺失值如果存在 if 单价 in df_cleaned.columns: df_cleaned[单价] df_cleaned[单价].fillna(df_cleaned[单价].median())处理异常值通过描述性统计和可视化如箱线图可以发现异常值。例如单价远高于或低于市场正常范围如低于1万/平或高于10万/平面积异常小或大如小于10平或大于500平。处理方式可以是设定合理的范围进行过滤。# 假设我们认为南京二手房单价合理范围在1万到10万之间 reasonable_unit_price_range (10000, 100000) df_cleaned df_cleaned[(df_cleaned[单价] reasonable_unit_price_range[0]) (df_cleaned[单价] reasonable_unit_price_range[1])]格式化与衍生字段原始数据中的字段可能需要拆分或计算以方便分析。拆分楼层从“中楼层/共6层”中提取“当前楼层”和“总楼层”。计算楼龄用当前年份减去“建筑年代”得到“楼龄”。区域标准化确保区域名称统一比如“鼓楼区”和“鼓楼”统一为“鼓楼”。# 示例拆分楼层信息假设原始字段名为‘floor_info’ def split_floor(floor_str): try: current, total floor_str.split(/) current current.replace(楼层, ) total total.replace(共, ).replace(层, ) return current, int(total) except: return None, None df_cleaned[[楼层类型, 总楼层]] df_cleaned[floor_info].apply(lambda x: pd.Series(split_floor(x))) # 计算楼龄 current_year pd.Timestamp.now().year df_cleaned[楼龄] current_year - df_cleaned[建筑年代]去重删除完全重复的记录。df_cleaned df_cleaned.drop_duplicates()注意数据清洗没有一成不变的规则每一步操作都需要结合业务常识来判断。例如删除异常值虽然能让图表更“好看”但也可能丢失了有价值的信息如顶级豪宅或特殊产权房。在清洗前后最好都保存一份数据快照方便回溯。3. 核心分析与可视化用图表讲述市场故事数据清洗完毕后就进入了最核心的分析与可视化环节。这里我主要使用matplotlib和seaborn这两个库。matplotlib是基础功能强大但稍显繁琐seaborn基于matplotlib提供了更高级的接口和更美观的默认样式非常适合统计图表。3.1 区域维度分析哪里是供应和价格的高地首先我们想知道南京各个区的房源供应量和价格水平。房源数量分布柱状图这是最直观的展示。可以清楚地看到鼓楼、江宁、浦口等区的挂牌量遥遥领先而建邺、玄武等核心区的房源量相对较少这符合市场常识——核心区新房和二手房供应都更稀缺。import matplotlib.pyplot as plt import seaborn as sns plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负号 # 设置seaborn样式 sns.set_style(whitegrid) # 绘制各区房源数量柱状图 district_count df_cleaned[区域].value_counts() plt.figure(figsize(12, 6)) ax sns.barplot(xdistrict_count.index, ydistrict_count.values, paletteviridis) plt.title(南京各区二手房挂牌数量分布, fontsize16) plt.xlabel(区域, fontsize14) plt.ylabel(房源数量, fontsize14) # 在柱子上方添加数量标签 for i, v in enumerate(district_count.values): ax.text(i, v 5, str(v), hacenter, fontsize10) plt.xticks(rotation45) # 旋转x轴标签防止重叠 plt.tight_layout() plt.show()区域单价对比箱线图或小提琴图箱线图可以展示每个区域单价的中位数、四分位数以及离散程度异常值。小提琴图则能同时展示分布形状和密度。从图中可以明显看出建邺、鼓楼、玄武等传统核心区的单价中位数和整体水平远高于六合、溧水等外围区域。同时核心区内部的单价差异箱体长度和胡须长度也更大说明这些区域内部楼盘档次分化更明显。# 绘制各区单价箱线图 plt.figure(figsize(14, 8)) sns.boxplot(x区域, y单价, datadf_cleaned, paletteSet2) plt.title(南京各区二手房单价分布箱线图, fontsize16) plt.xlabel(区域, fontsize14) plt.ylabel(单价 (元/平方米), fontsize14) plt.xticks(rotation45) plt.tight_layout() plt.show() # 绘制各区单价小提琴图更直观显示分布密度 plt.figure(figsize(14, 8)) sns.violinplot(x区域, y单价, datadf_cleaned, palettemuted, innerquartile) plt.title(南京各区二手房单价分布小提琴图, fontsize16) plt.xlabel(区域, fontsize14) plt.ylabel(单价 (元/平方米), fontsize14) plt.xticks(rotation45) plt.tight_layout() plt.show()3.2 价格与面积关系分析市场的供需结构总价和面积是购房者最关心的两个指标。分析它们的关系能看出市场主力的产品类型。总价与面积散点图带区域颜色区分将每个房源以点的形式画在图上X轴是面积Y轴是总价。我们可以用颜色来区分不同区域。这张图能直观揭示几个规律1. 点形成的“云团”大致呈线性上升趋势即面积越大总价越高。2. 相同面积下不同区域的总价点位于不同高度直观反映了区域溢价如建邺区的点普遍比浦口区同面积的点位置高。3. 可以观察到一些偏离主云团的“离群点”可能是别墅、顶级学区房或者数据噪声。plt.figure(figsize(12, 8)) # 使用hue参数按区域着色 palette指定调色板 scatter sns.scatterplot(x面积, y总价, hue区域, datadf_cleaned, palettetab20c, s60, alpha0.7) plt.title(南京二手房总价与面积关系散点图按区域着色, fontsize16) plt.xlabel(面积 (平方米), fontsize14) plt.ylabel(总价 (万元), fontsize14) plt.legend(bbox_to_anchor(1.05, 1), locupper left) # 将图例放在图表外侧 plt.tight_layout() plt.show()单价分布直方图与密度曲线观察整个南京二手房单价的集中区间。通过绘制直方图并叠加核密度估计KDE曲线可以发现单价主要集中在2.5万到4.5万/平方米这个区间呈近似正态分布但略有右偏高价房源拉长了尾部。plt.figure(figsize(10, 6)) sns.histplot(df_cleaned[单价], kdeTrue, bins50, colorskyblue, edgecolorblack) plt.title(南京二手房单价分布直方图, fontsize16) plt.xlabel(单价 (元/平方米), fontsize14) plt.ylabel(频数, fontsize14) plt.axvline(df_cleaned[单价].mean(), colorred, linestyle--, labelf均值: {df_cleaned[单价].mean():.0f}) plt.axvline(df_cleaned[单价].median(), colorgreen, linestyle--, labelf中位数: {df_cleaned[单价].median():.0f}) plt.legend() plt.tight_layout() plt.show()3.3 多维度交叉分析挖掘更深层次的洞察单一维度的分析还不够我们需要交叉分析来回答更复杂的问题。楼龄对单价的影响散点图回归线通常楼龄越新单价越高。我们可以绘制楼龄和单价的散点图并添加一条线性回归趋势线来量化这种关系。结果可能显示负相关趋势但趋势线的斜率即楼龄每增加一年单价下降多少能给出一个粗略的量化参考。需要注意的是这个关系受区域、装修等因素干扰很大。plt.figure(figsize(10, 6)) sns.regplot(x楼龄, y单价, datadf_cleaned, scatter_kws{s:20, alpha:0.5}, line_kws{color:red}) plt.title(楼龄与单价关系散点图带回归线, fontsize16) plt.xlabel(楼龄 (年), fontsize14) plt.ylabel(单价 (元/平方米), fontsize14) plt.gca().invert_xaxis() # 反转X轴让楼龄小的在右边更符合认知 plt.tight_layout() plt.show()装修情况与单价的关系分组柱状图比较“精装”、“简装”、“毛坯”在不同区域的单价均值。可以绘制分组柱状图X轴是区域每组柱子代表不同的装修情况柱子高度代表该条件下的平均单价。这张图能揭示1. 在同一区域内精装房的单价溢价是否明显。2. 在不同区域之间装修带来的溢价幅度是否相同。# 计算各区域、各装修情况的平均单价 pivot_table df_cleaned.pivot_table(values单价, index区域, columns装修情况, aggfuncmean) # 绘制分组柱状图 pivot_table.plot(kindbar, figsize(14, 8), width0.8) plt.title(不同区域及装修情况下二手房平均单价对比, fontsize16) plt.xlabel(区域, fontsize14) plt.ylabel(平均单价 (元/平方米), fontsize14) plt.xticks(rotation45) plt.legend(title装修情况) plt.tight_layout() plt.show()实操心得可视化不是图表越多越好而是要服务于核心结论。在开始画图前先问自己我想通过这张图回答什么问题是看分布、比大小、找关系还是看趋势选择最合适的图表类型。另外seaborn的pairplot函数可以快速生成数据集中多个数值变量两两之间的散点图和分布图用于探索性数据分析EDA非常高效但在最终报告中使用时要有选择地提取关键子图避免信息过载。4. 从Jupyter Notebook到可交付成果源码组织与PPT生成分析做完图表也画好了但项目还没结束。我们需要把代码整理好方便自己日后复用和他人理解同时还要将分析结论有效地呈现给非技术背景的听众比如业务部门或领导这就需要制作PPT。4.1 源码的组织与封装一个杂乱无章的.ipynb文件不是好作品。我习惯将项目按功能模块拆分提高可读性和可维护性。推荐的项目结构如下nanjing_house_analysis/ ├── data/ │ ├── raw/ # 存放原始数据 │ │ └── nanjing_second_hand.csv │ └── processed/ # 存放清洗后的数据 │ └── cleaned_data.csv ├── notebooks/ # Jupyter Notebook文件用于探索性分析 │ └── 01_eda_visualization.ipynb ├── src/ # 核心源代码Python模块 │ ├── __init__.py │ ├── data_cleaner.py # 数据清洗函数封装 │ ├── visualizer.py # 可视化图表生成函数封装 │ └── analyzer.py # 核心分析逻辑函数封装 ├── output/ # 生成的图表、报告等 │ ├── figures/ # 保存的图片PNG/SVG │ │ ├── district_count.png │ │ ├── price_vs_area.png │ │ └── ... │ └── report/ # 生成的报告HTML/PDF ├── requirements.txt # 项目依赖包列表 ├── main.py # 主程序入口可一键运行整个分析流程 └── README.md # 项目说明文档关键代码封装示例 (src/visualizer.py):# visualizer.py import matplotlib.pyplot as plt import seaborn as sns import pandas as pd class HousePriceVisualizer: def __init__(self, df, output_dir./output/figures): self.df df self.output_dir output_dir # 设置中文字体和样式 plt.rcParams[font.sans-serif] [SimHei, DejaVu Sans] plt.rcParams[axes.unicode_minus] False sns.set_style(whitegrid) def plot_district_count(self, saveFalse): 绘制各区房源数量柱状图 district_count self.df[区域].value_counts() plt.figure(figsize(12, 6)) ax sns.barplot(xdistrict_count.index, ydistrict_count.values, paletteviridis) plt.title(南京各区二手房挂牌数量分布, fontsize16) plt.xlabel(区域, fontsize14) plt.ylabel(房源数量, fontsize14) for i, v in enumerate(district_count.values): ax.text(i, v 5, str(v), hacenter, fontsize10) plt.xticks(rotation45) plt.tight_layout() if save: plt.savefig(f{self.output_dir}/district_count.png, dpi300, bbox_inchestight) plt.show() plt.close() def plot_price_vs_area(self, saveFalse): 绘制总价-面积散点图按区域着色 plt.figure(figsize(12, 8)) scatter sns.scatterplot(x面积, y总价, hue区域, dataself.df, palettetab20c, s60, alpha0.7) plt.title(南京二手房总价与面积关系散点图按区域着色, fontsize16) plt.xlabel(面积 (平方米), fontsize14) plt.ylabel(总价 (万元), fontsize14) plt.legend(bbox_to_anchor(1.05, 1), locupper left) plt.tight_layout() if save: plt.savefig(f{self.output_dir}/price_vs_area.png, dpi300, bbox_inchestight) plt.show() plt.close() # ... 其他绘图函数这样在主程序main.py中调用就变得非常清晰# main.py from src.data_cleaner import clean_data from src.visualizer import HousePriceVisualizer def main(): # 1. 数据清洗 df_cleaned clean_data(data/raw/nanjing_second_hand.csv) df_cleaned.to_csv(data/processed/cleaned_data.csv, indexFalse) # 2. 可视化 visualizer HousePriceVisualizer(df_cleaned) visualizer.plot_district_count(saveTrue) visualizer.plot_price_vs_area(saveTrue) # ... 调用其他绘图函数 if __name__ __main__: main()4.2 使用Python自动化生成PPT报告手动将图表复制粘贴到PPT里既繁琐又容易出错。我们可以用python-pptx库来自动化这个过程。思路是创建一个PPT模板然后用代码定位到模板中的占位符Placeholder将分析结论文本和生成的图片插入到指定位置。步骤一设计PPT模板在PowerPoint或Keynote中设计一个简单的模板包含你需要的版式。例如标题页项目名称、分析人、日期。目录页列出主要分析章节。内容页通常包含标题、内容文本框用于写结论和图片占位符。为每个要插入的图表预留一个图片占位符并给这些占位符起一个容易识别的名字在PPT的“选择窗格”中修改形状名称。步骤二编写PPT生成脚本# generate_ppt.py from pptx import Presentation from pptx.util import Inches, Pt import os def create_analysis_ppt(figures_dir, output_ppt_path, template_pathtemplate.pptx): 根据图表和分析结论生成PPT :param figures_dir: 存放图表图片的目录 :param output_ppt_path: 输出的PPT文件路径 :param template_path: PPT模板路径 prs Presentation(template_path) # 1. 标题页 (假设模板第一页是标题页) title_slide prs.slides[0] title title_slide.shapes.title subtitle title_slide.placeholders[1] # 假设第二个占位符是副标题 title.text 南京二手房市场数据分析报告 subtitle.text 基于Python的数据可视化分析\n报告日期2023年10月 # 2. 添加目录页 (在模板后新增一页使用标题和内容版式) slide_layout prs.slide_layouts[1] # 假设版式索引1是“标题和内容” slide prs.slides.add_slide(slide_layout) title slide.shapes.title title.text 报告目录 content slide.shapes.placeholders[1] tf content.text_frame tf.text 1. 数据概览与清洗\n2. 区域市场分析\n3. 价格与面积关系\n4. 多维度交叉分析\n5. 核心结论与建议 # 3. 添加“区域市场分析”页并插入图片 slide prs.slides.add_slide(slide_layout) title slide.shapes.title title.text 2. 区域市场分析供应与价格 content slide.shapes.placeholders[1] tf content.text_frame tf.text • 鼓楼、江宁、浦口挂牌量最大占据市场主流。\n• 建邺、鼓楼、玄武为单价第一梯队均价显著高于其他区域。\n• 核心区域内部房价分化明显选择空间大但需仔细甄别。 # 插入“区域房源数量”图 img_path os.path.join(figures_dir, district_count.png) left Inches(0.5) top Inches(2) # 放在内容文本框下方 slide.shapes.add_picture(img_path, left, top, widthInches(4.5)) # 插入“区域单价分布”图假设另一张图叫district_price_box.png img_path2 os.path.join(figures_dir, district_price_box.png) left2 Inches(5) # 放在第一张图右边 slide.shapes.add_picture(img_path2, left2, top, widthInches(4.5)) # 4. 类似地添加其他分析页... # ... 插入“总价-面积散点图”、“单价分布直方图”等 # 5. 保存PPT prs.save(output_ppt_path) print(fPPT报告已生成{output_ppt_path}) if __name__ __main__: create_analysis_ppt(./output/figures, ./output/report/nanjing_house_analysis.pptx)踩坑提醒python-pptx对PPT模板中的占位符索引和类型比较敏感。最可靠的方式不是用索引如placeholders[1]而是遍历幻灯片中的所有形状slide.shapes根据形状的名称shape.name来定位。你需要在PPT模板中为每个文本框和图片占位符设置一个独特的、易于识别的名称例如“title_box”, “content_box”, “chart1_placeholder”。这样代码的鲁棒性会强很多。另外插入图片时要注意调整位置和大小可能需要多次调试才能获得满意的排版。5. 项目复盘与扩展思考完成整个流程后回过头看这个项目不仅仅是一次数据绘图练习更是一个典型的数据分析Pipeline的缩影数据获取 - 清洗 - 探索性分析 - 可视化 - 报告生成。每个环节都有值得深挖的地方。关于数据源本项目假设数据已经存在。在实际中获取数据可能是一大挑战。你可以编写爬虫使用requests、BeautifulSoup、Scrapy等从房产网站定时抓取但务必遵守网站的robots.txt协议和相关法律法规。更稳妥的方式是使用公开的数据集或向公司内部的数据部门申请。关于分析深度本文展示的是描述性统计分析告诉你市场“是什么样”。更进一步可以做推断性分析或机器学习建模。例如预测房价以单价或总价为因变量面积、区域、楼龄、装修等为特征构建回归模型如线性回归、随机森林、XGBoost预测房源价格并分析哪些特征对价格影响最大特征重要性分析。房源聚类根据面积、总价、区域等特征对房源进行聚类如K-Means发现市场上不同的房源细分类型如“刚需小户型”、“改善大平层”、“核心区豪宅”等。时间序列分析如果你有不同时间点的历史数据可以分析房价随时间的变化趋势预测未来走势。关于可视化进阶matplotlib和seaborn足以应对大多数需求。如果想制作交互式图表或更复杂的可视化可以学习Plotly或Pyecharts。它们能生成可在网页上交互的图表缩放、拖拽、显示数据点详情非常适合制作数据看板Dashboard。关于项目部署为了让分析流程自动化你可以将脚本部署到服务器定期运行例如使用cron定时任务。更进一步可以用Flask或Streamlit快速搭建一个简单的Web应用上传数据文件后自动完成分析并生成可视化报告和PPT实现一个轻量级的分析工具。最后源码和PPT模板的打包分享很有意义。在分享时确保README.md文件写清楚1. 项目目的2. 环境配置步骤pip install -r requirements.txt3. 如何运行代码4. 数据格式说明。一个清晰的项目结构和完善的文档能让你的作品显得专业也方便他人协作或学习。这个项目里用到的技术栈Pandas, Matplotlib/Seaborn, python-pptx都是Python生态中非常通用和强大的工具掌握它们你就能处理生活中、工作中遇到的很多类似的数据分析和自动化报告任务。本文还有配套的精品资源点击获取