ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python二手房数据分析源码:从CSV清洗到可视化全流程

Python二手房数据分析源码:从CSV清洗到可视化全流程 简介这份资源是面向高校学生与Python初学者的一套二手房数据分析完整项目可直接用于毕业设计、期末大作业或课程设计场景。项目以Python为核心围绕二手房数据的采集、清洗与可视化分析展开包含从原始数据到清洗后数据的多版本CSV文件便于对照理解数据预处理流程。压缩包共157个文件涵盖18个py源码、18个csv数据集、15个html页面、11个js脚本以及65张png图表另附docx文档说明与pptx演示资料整体约48.05MB代码注释齐全新手也能看懂。目前已有127人学习下载。项目经过严格调试部署简单下载后即可运行界面美观、功能完善能帮助读者快速掌握数据分析项目的完整实现思路并直接作为高分作业提交使用。1. 从一份二手房 CSV 说起这套 Python 分析源码到底能干什么如果你手头正好有一份ershoufang-origin-utf8.csv这样的二手房原始数据打开一看字段乱、编码杂、价格带「万」字、楼层写「中楼层(共6层)」想做个能交差的课程设计却不知道从哪下手那这套基于 Python 的二手房数据分析源码就是冲这个场景来的。它把从原始 CSV 到清洗、统计、可视化、结论输出的整条链路都写好了还配了文档说明和 PPT 资料代码里带注释新手照着跑也能看懂每一步在干嘛。适合谁期末大作业、课程设计、毕业设计这类需要「完整可运行 有分析结论 能讲清楚」的场合。它不追求算法多前沿追求的是流程完整、结果能复现、答辩时讲得出逻辑。下面我按自己拆包的习惯把这份资源从数据到结论走一遍顺带把几个容易翻车的地方标出来。2. 数据文件与编码先搞清楚你拿到的是哪一版 CSV2.1 原始数据、清洗数据、编码版本三者的关系这套资源里 CSV 文件不少名字里带origin、clean、utf8、ansi、v1.1这些标记很多人第一眼会懵。我先把它们的关系理清楚不然后面读进来一堆乱码还以为是代码问题。从文件名能看出两条线一条是数据加工阶段origin是原始抓取或导出的数据clean是清洗后的另一条是字符编码utf8和ansi是同一份数据的不同编码版本。v1.1是清洗规则的版本号说明清洗逻辑迭代过一次。ershoufang - 20000.csv从命名看是两万条量级的样本ershoufang.csv则像是主数据文件。为什么同一份数据要存两种编码因为 Windows 上 Excel 默认按 ANSI简体中文环境是 GBK打开 CSV你给它一个 UTF-8 文件中文列名和小区名直接变乱码。反过来有些 Python 读取脚本如果没指定编码在 Windows 上默认走的也是本地编码。所以作者把两种编码都留了一份本质是让你在不同工具链下都能少踩一个坑。文件名阶段编码用途ershoufang-origin-utf8.csv原始UTF-8Python 读取、跨平台ershoufang-origin-ansi.csv原始ANSI/GBKExcel 直接打开ershoufang-clean-utf8-v1.1.csv清洗后UTF-8建模、可视化输入ershoufang-clean-ansi-v1.1.csv清洗后ANSI/GBK人工核对、Excel 查看ershoufang - 20000.csv样本视文件而定快速试跑、演示ershoufang.csv主数据视文件而定完整分析选哪份取决于你要干什么。跑代码做分析一律用clean-utf8-v1.1想用 Excel 肉眼核对清洗结果用clean-ansi-v1.1想验证清洗脚本本身才回头去读origin版本。2.2 用 pandas 正确读入并确认编码读 CSV 第一步不是急着分析是先确认读进来的东西没坏。下面这段是我一般会先跑的探针代码。import pandas as pd # 优先用 utf-8 读如果报 UnicodeDecodeError 再换 gbk def load_csv(path): for enc in (utf-8, gbk, gb18030): try: df pd.read_csv(path, encodingenc) print(f成功读取: {path} | 编码: {enc} | 形状: {df.shape}) return df except UnicodeDecodeError: continue raise ValueError(三种编码都读不了检查文件是否损坏) df load_csv(ershoufang-clean-utf8-v1.1.csv) print(df.columns.tolist()) print(df.head(3))逻辑说明gb18030是 GBK 的超集放在最后兜底能覆盖绝大多数简体中文 Windows 导出的文件。参数上encoding不指定时 pandas 在部分环境会默认 UTF-8遇到 ANSI 文件直接抛UnicodeDecodeError所以显式轮询更稳。读进来后先看shape和columns如果列名出现\ufeff这种前缀说明文件带 BOM读取时加encodingutf-8-sig即可。提示如果df.shape的列数明显少于你预期的字段数八成是分隔符不对试试sep;或sep\t。3. 清洗与特征处理把「万」「平米」「中楼层」变成能算的数3.1 清洗脚本在做什么从字符串到数值的映射二手房数据最烦的就是字段里混着单位和描述。总价写「350万」单价写「45000元/平米」面积写「89.5平米」楼层写「中楼层(共6层)」朝向写「南 北」。这些字段不处理df.describe()一个都统计不出来。清洗的核心就三件事去单位、转数值、拆复合字段。下面这段是我按这套资源的清洗思路复现的逻辑和clean-v1.1对得上。import pandas as pd import numpy as np import re df pd.read_csv(ershoufang-origin-utf8.csv, encodingutf-8) # 1. 总价: 350万 - 350.0 def parse_price(x): if pd.isna(x): return np.nan m re.search(r([\d.]), str(x)) return float(m.group(1)) if m else np.nan df[总价_万] df[总价].apply(parse_price) # 2. 面积: 89.5平米 - 89.5 df[面积_平米] df[面积].apply(parse_price) # 3. 单价: 有些数据没有用总价和面积反推 df[单价_元每平] df[总价_万] * 10000 / df[面积_平米] # 4. 楼层: 中楼层(共6层) - 楼层位置 总层数 def parse_floor(x): if pd.isna(x): return pd.Series([np.nan, np.nan]) s str(x) pos 中 if 低 in s: pos 低 elif 高 in s: pos 高 m re.search(r共(\d)层, s) total int(m.group(1)) if m else np.nan return pd.Series([pos, total]) df[[楼层位置, 总层数]] df[楼层].apply(parse_floor) # 5. 丢弃关键字段缺失的行 df df.dropna(subset[总价_万, 面积_平米]) df df[df[面积_平米] 0] df.to_csv(ershoufang-clean-utf8-v1.1.csv, indexFalse, encodingutf-8) print(清洗完成剩余行数:, len(df))逻辑说明parse_price用正则只抓数字部分兼容「350万」「350.5万」「350」几种写法。单价反推这一步很关键因为原始数据里单价经常缺失或格式不统一用总价乘一万除以面积得到的是「元/平米」量纲统一后才能做分布分析。楼层拆成位置和总层数两个字段是为了后面能算「中间楼层溢价」这类结论——只留一个「中楼层(共6层)」字符串任何统计都做不了。参数上dropna的subset只卡总价和面积其他字段缺失先留着避免样本被砍太狠。面积_平米 0是防除零也是防那种面积填 0 的脏数据。3.2 特征工程哪些字段值得留哪些是噪音清洗完不是所有列都要进分析。我一般会按「能不能量化、有没有区分度」两个标准筛一遍。能直接量化的总价、单价、面积、总层数、房龄如果有建成年份。能编码成类别的楼层位置低/中/高、朝向南/北/东南等、装修情况、有无电梯。这些字段在可视化阶段能直接分组对比。噪音字段通常是房源标题、小区详细地址、经纪人姓名、挂牌时间戳如果只做截面分析。标题里信息量大但非结构化除非你要做文本挖掘否则留着只会让 DataFrame 变宽。地址如果只到小区级别可以提取「区域」做分组再细就没意义了。# 从地址里提取区域用于分组统计 df[区域] df[地址].astype(str).str.extract(r^(\w?区)) # 朝向做简化: 只保留第一个方向 df[主朝向] df[朝向].astype(str).str.split().str[0] # 房龄: 假设有建成年份字段 if 建成年份 in df.columns: df[房龄] 2024 - pd.to_numeric(df[建成年份], errorscoerce)str.extract用非贪婪匹配抓「XX区」是因为地址格式通常是「朝阳区XX路XX号」贪婪匹配会把后面全吞进去。errorscoerce让转不了的年份变 NaN而不是直接报错中断。注意区域提取依赖地址格式统一。如果有的地址写「朝阳区」有的写「北京市朝阳区」正则需要调整否则会漏掉一批。清洗后建议df[区域].value_counts(dropnaFalse)看一眼缺失比例。4. 分析与可视化把均价、面积、区域差异讲成结论4.1 描述性统计与分组聚合数据洗干净后第一步是看整体分布第二步是按维度拆开看差异。这套资源的分析部分基本围绕「均价」「面积」「区域」「楼层」四个维度展开。import pandas as pd df pd.read_csv(ershoufang-clean-utf8-v1.1.csv, encodingutf-8) # 整体均价和面积分布 print(整体均价(元/平):, df[单价_元每平].mean().round(0)) print(面积中位数(平):, df[面积_平米].median()) print(df[[总价_万, 单价_元每平, 面积_平米]].describe().round(1)) # 按区域看均价 region_stat df.groupby(区域).agg( 房源数(单价_元每平, count), 均价(单价_元每平, mean), 中位面积(面积_平米, median) ).round(0).sort_values(均价, ascendingFalse) print(region_stat) # 按楼层位置看均价 floor_stat df.groupby(楼层位置)[单价_元每平].mean().round(0) print(floor_stat)逻辑说明groupby后接agg可以一次算出多个指标比循环高效。count用单价字段而不是总价是因为单价缺失更少前面反推过。sort_values降序排列让均价最高的区域排前面答辩时一眼能看出结论。参数上round(0)把浮点压成整数均价精确到元就够了小数位反而干扰阅读。如果某个区域房源数只有个位数它的均价参考价值很低建议加个过滤region_stat[region_stat[房源数] 30]。4.2 可视化三张图讲清楚一个结论分析类项目答辩时图比表管用。这套资源的可视化一般用 matplotlib 或 pyecharts我按 matplotlib 给一套能直接跑的。import matplotlib.pyplot as plt import pandas as pd df pd.read_csv(ershoufang-clean-utf8-v1.1.csv, encodingutf-8) plt.rcParams[font.sans-serif] [SimHei] # 中文显示 plt.rcParams[axes.unicode_minus] False fig, axes plt.subplots(1, 3, figsize(18, 5)) # 图1: 单价分布直方图 axes[0].hist(df[单价_元每平].dropna(), bins50, color#4C72B0) axes[0].set_title(单价分布) axes[0].set_xlabel(元/平米) # 图2: 各区域均价条形图 region_mean df.groupby(区域)[单价_元每平].mean().sort_values() axes[1].barh(region_mean.index, region_mean.values, color#55A868) axes[1].set_title(各区域均价) axes[1].set_xlabel(元/平米) # 图3: 面积与总价散点 axes[2].scatter(df[面积_平米], df[总价_万], alpha0.3, s8) axes[2].set_title(面积-总价关系) axes[2].set_xlabel(面积(平米)) axes[2].set_ylabel(总价(万)) plt.tight_layout() plt.savefig(analysis_result.png, dpi150) plt.show()逻辑说明SimHei是 Windows 自带中文字体Linux 上可能没有换成WenQuanYi Micro Hei或Noto Sans CJK SC。axes.unicode_minus False解决负号显示成方块的问题。直方图bins50是经验值数据量两万左右时分布看得比较细。散点图alpha0.3让重叠点透出来s8控制点大小不然两万个点糊成一团。提示如果散点图出现明显的离群点比如面积 500 平但总价 50 万先回清洗阶段查是不是单位解析错了别急着在可视化里裁掉。5. 避坑与排查跑这套源码最容易翻车的五个地方5.1 编码报错 UnicodeDecodeError现象pd.read_csv直接抛UnicodeDecodeError: utf-8 codec cant decode byte...。原因文件是 ANSI/GBK 编码但读取时用了默认 UTF-8。解决按 2.2 的轮询写法依次试utf-8、gbk、gb18030。如果文件带 BOM用utf-8-sig。别去改文件编码改读取参数更快。5.2 中文列名变乱码现象df.columns打印出来是[\xe6\x80\xbb\xe4\xbb\xb7]这种或者显示成问号。原因读取编码和文件实际编码不匹配或者终端本身不支持中文输出。解决先确认读取编码正确再确认终端编码。Windows 命令行跑chcp 65001切 UTF-8。如果是在 IDE 里跑检查文件编码设置。5.3 单价算出天文数字或负数现象单价_元每平出现几百万甚至负数。原因总价单位没统一。有的行写「350万」有的写「350」解析后一个当万一个当元反推单价就差了 10000 倍。负数通常是面积字段混进了「-」或解析到了错误数字。解决在parse_price后加一步校验df df[(df[总价_万] 10) (df[总价_万] 10000)]把明显不合理的总价区间卡掉。面积同理设个10 面积 1000的合理区间。5.4 groupby 后区域数量对不上现象明明有 10 个区groupby(区域)只出来 6 个。原因区域提取正则没覆盖所有地址格式部分行提取结果是 NaN被 groupby 默认丢弃了。解决df[区域].isna().sum()看缺失量df[df[区域].isna()][地址].head(20)看漏掉的格式补正则。或者用dropnaFalse保留 NaN 组先看清楚再决定怎么处理。5.5 可视化中文显示成方块现象图里标题、轴标签的中文全是方框。原因matplotlib 默认字体不含中文。解决plt.rcParams[font.sans-serif] [SimHei]Linux 上换成系统里实际有的中文字体。查系统字体用fc-list :langzh。改完记得重启 kernelrcParams 在部分环境不会热生效。6. 进阶技巧把分析结论做成能讲三分钟的答辩素材跑通代码只是及格线答辩时老师不会看你df.head()他要的是「你发现了什么」。这套资源配了 PPT 资料但 PPT 是壳里面的结论得你自己从数据里挖。我一般会从三个角度切区域差异、面积段分布、楼层溢价。区域差异最好讲。按 4.1 的region_stat拿到各区域均价排序挑最高和最低两个区对比说清楚价差倍数。比如「均价最高的区是最低区的 2.3 倍」这一句就是一个结论。再配一张条形图视觉冲击直接拉满。面积段分布适合讲刚需和改善的差异。把面积切成60 以下、60-90、90-120、120 以上四段看每段的房源占比和均价。bins [0, 60, 90, 120, 1000] labels [60以下, 60-90, 90-120, 120以上] df[面积段] pd.cut(df[面积_平米], binsbins, labelslabels) seg_stat df.groupby(面积段, observedTrue).agg( 房源数(单价_元每平, count), 均价(单价_元每平, mean), 占比(单价_元每平, lambda x: len(x) / len(df)) ).round(2) print(seg_stat)pd.cut做分箱observedTrue避免类别型 groupby 产生空组。占比用 lambda 算比单独再除一次简洁。如果发现 60-90 段房源最多但均价不是最低说明刚需盘竞争激烈但价格没被压下来这就是一个能展开讲的点。楼层溢价是加分项。用 3.1 拆出来的楼层位置做分组看低/中/高楼层均价差异。如果中间楼层明显贵可以结合「采光」「电梯」解释如果差异不大说明这个城市购房者对楼层不敏感也是个结论。最后说个我自己的习惯每次跑完分析我会把region_stat、seg_stat、floor_stat三个表导出成 CSV答辩前打印出来贴在电脑边上。老师问哪个数直接念不用现场翻代码。这套源码的文档说明和 PPT 资料能帮你把框架搭起来但真正让答辩稳的是你自己跑过一遍、改过参数、知道每个数字从哪来的那份底气。从那以后我每次做数据分析类项目都强制自己把关键统计表导出留档不再只依赖 notebook 里的输出。希望帮到你。本文还有配套的精品资源点击获取
返回列表