二手车交易数据分析与可视化:从数据清洗到pyecharts实战

发布时间:2026/9/8 14:19:36
二手车交易数据分析与可视化:从数据清洗到pyecharts实战 简介一套覆盖数据采集、存储、分析与可视化全流程的二手车交易数据分析系统面向数据分析初学者、Python开发者及需要综合实战项目的学生。项目基于Python爬虫抓取交易平台结构化字段配合Django/Flask后端与前端页面搭建展示层通过MySQL脚本完成数据落库并借助Pandas等库进行清洗和统计最终用交互式图表呈现价格分布与市场趋势包含箱线图等统计图表示例。资源包共104个文件以31个py源码、16个html页面、16个js脚本和4个css样式为主另含SQL建表脚本、bat启动脚本及requirements依赖清单整体仅1.63MB结构紧凑、目录清晰便于分模块学习。已有297人学习下载适合用来理解企业级项目分层思路也可作为课程设计或毕业设计的参考底稿。 二手车交易这块市场信息差永远是最大的成本。同样一台车有人挂高价等三个月卖不掉有人低价收回来两天就出手。问题不是车不好而是大多数人根本不了解自己所在城市的真实交易行情。我之前花了几个周末把某二手车平台上几千条在售数据拉了下来做了整套“二手车交易数据分析与可视化系统”从清洗、特征加工到可视化图表一次跑通不敢说多高深但对想入行数据分析、或者自己买卖二手车想心里有底的朋友绝对有参考价值。这篇文章就把完整思路和关键代码拆开讲清楚。1. 数据从哪来不是只有爬虫一条路1.1 公开数据集是起步最快的方式很多人一听到“数据分析项目”第一反应就是“我要去爬数据”。出发点是好的但对一个练手项目来说爬虫带来的麻烦往往比数据本身还多——反爬、封IP、验证码、动态渲染页面一套流程折腾下来可能一周就过去了真正花在分析上的时间反而没多少。我的建议是第一步先在公开数据集平台找现成的二手车交易数据。例如Kaggle上的二手车数据集、和鲸社区的二手车分析案例、GitHub上的开源二手车爬取结果字段一般都很齐全通常包含车型名称品牌、车系、具体型号上牌日期决定车龄表显里程公里数变速箱类型自动/手动排量和排放标准所在城市新车指导价、当前标价卖家类型个人/车商用现成数据的好处是字段结构相对规范你可以把主要精力放在清洗逻辑和分析模型上。等这套流程跑通了再去写爬虫补充自己城市的新数据就有了明确的目标和验收标准。1.2 爬虫方案要解决的反爬与字段缺失如果确实需要自己采集我建议绕开那些反爬很凶的大平台优先选择信息聚合类站点或者二三线交易平台的移动端接口。实测下来移动端接口返回JSON格式字段命名很有规律解析成本比解析HTML低很多。请求时带上常规的User-Agent和Referer控制请求频率在每秒1到2次基本不会触发风控。但爬虫真正的坑不是反爬而是字段缺失。很多车源没有标注变速箱有些历史车源的下架时间就是“无”排放标准在部分城市字段直接被折叠。所以清洗脚本里必须做好字段缺失率统计单项缺失超过30%的字段建议直接丢弃低于5%的用众数或中位数填充。这一步决定了后续分析是否可信值得多花时间。2. 数据清洗与特征工程二手车数据最脏的几个角落2.1 价格字段的坑比想象中多价格是最核心的分析字段但原始数据里的价格可没那么干净。最常见的几个问题单位不统一。有的标“万”有的标“元”混在一起就是灾难。有的车源标的是“首付价”或“一口价”含义完全不同。存在极低或极高的异常值比如同一款车有人标0.5万多半是引流帖。我的处理方式是先统一转成元再按正态分布剔除极端值。简单写个清洗函数import pandas as pd import numpy as np def clean_price(df, colprice): # 统一单位假设原始数据有price_unit列万元转元 df[price_num] df.apply( lambda x: x[col] * 10000 if x.get(price_unit) 万 else x[col], axis1 ) # 剔除价格小于1万或大于100万的可疑数据按车型平均值再判断 df df[(df[price_num] 10000) (df[price_num] 1000000)] # 按品牌分组剔除组内均值±3倍标准差之外的数据 def filter_outlier(group): m, std group[price_num].mean(), group[price_num].std() return group[(group[price_num] m - 3*std) (group[price_num] m 3*std)] df df.groupby(brand, group_keysFalse).apply(filter_outlier) return df为什么按品牌分组剔除而不是全量剔除因为不同品牌的价位带差异很大3万的五菱和30万的奔驰放一起算均值会把正常值误杀。分品牌清洗才符合二手车市场本身的逻辑。2.2 车龄与里程的标准化上牌日期字段通常是字符串比如“2018-05-01”需要转成datetime类型然后计算车龄df[listing_date] pd.to_datetime(df[listing_date]) df[reg_date] pd.to_datetime(df[reg_date]) df[car_age] (df[listing_date] - df[reg_date]).dt.days / 365.25里程字段有时会出现“表显里程”和“实表里程”两个值优先用实表缺失时用表显。里程大于50万公里的多数是运营车辆和普通家用车放在一起分析会把均价拉低这类数据建议直接过滤。2.3 新增两个有分析价值的派生特征清洗完基础字段后我习惯再生成两个派生特征它们在后面的可视化中很好用百公里车价 当前价格 / 里程数折算成每公里的持有成本。这个特征适合比较同价位两辆车哪个更“划算”。指导价折价率 当前价格 / 新车指导价。这个值能直观反映车辆保值程度折价率越低贬值越猛。df[price_per_km] df[price_num] / df[mileage].replace(0, np.nan) df[depreciation_rate] df[price_num] / df[guide_price].replace(0, np.nan)需要注意新车指导价也不是每家都填缺失率如果太高折价率特征就只用来做定性分析不进入后续数值建模。3. 先想清楚分析什么交易分析的五个核心问题数据洗干净之后不要急着画图。做数据分析项目最怕的就是“为可视化而可视化”——画了十张图每张都在展示同一件事。我拿到数据后先明确了五个业务问题所有图表都围绕它们展开3.1 价格分布与主流区间消费者最关心的问题就是“多少钱能买到合适的车”。通过价格直方图可以看到当前市场上哪几个价格区间车源最密集是10万以下刚需代步还是20万级合资B级车还是50万以上豪车。这个信息对车商定价、对买家做预算都有直接参考价值。3.2 品牌溢价与保值率不同品牌的二手车溢价完全不在一个量级。丰田、本田这种日系车三年保值率能到70%以上部分豪华品牌可能三年直接腰斩。用品牌维度聚合平均标价、平均折价率可以得到一张“品牌保值梯队图”买卖双方都可以参考。3.3 车龄对价格的衰减规律车龄是最强的价格影响因素。一台车从第1年到第8年折价曲线是前陡后缓的前3年掉价最猛过了5年后反而越来越平。用散点图加拟合线把这个衰减规律可视化买家和卖家都能找到自己的最佳交易窗口。3.4 城市与区域差异同样的日系家用车南方城市和北方城市的流通价可能差5%到8%。一些新能源车型在不同城市的补贴政策也会影响二手车价格。数据里如果城市字段完整按省份聚合画地图就能看到二手车交易热度和价格水平的地域差异。3.5 里程与车龄的交叉作用只看车龄不看里程很容易得出错误结论。一辆3年开2万公里的车和一辆3年开8万公里的车车况和价格完全不同。用散点图把车龄和里程同时映射到价格上能更立体地理解车况对价格的综合影响。4. 可视化选型与实践为什么我用 pyecharts4.1 几种可视化方案的横向对比我身边朋友做数据分析可视化走的路线差异很大。这里列个对比大家可以根据自己的场景选方案优点缺点适合场景Excel零学习成本基础图表齐全数据量一大就卡交互弱临时看数PowerBI / Tableau拖拽式建模交互功能强授权费用不低本地大数据集吃力企业报表阿里云QuickBI等大屏套件模板好看实时刷新配置复杂私有化部署成本高企业大屏展示Python matplotlib / seaborn灵活到底统计图表专业审美需要自己调数据探索Python pyecharts图表交互好中文文档友好可嵌入网页定制太花哨的自定义能力有限中小型项目、个人作品我这次选的是pyecharts。原因主要有三个第一它生成的图表是JavaScript渲染的有悬浮提示、缩放、拖拽等交互适合在浏览器里展示第二它是国产库中文文档齐全遇到问题搜索一下就能找到答案第三它可以直接渲染成HTML文件不需要起服务就能打开交付和演示都很方便。4.2 目录结构与分析流程设计项目不是把所有脚本放一个文件夹里跑我建议按可复用的模块化方式组织car_analysis/ ├── data/ │ ├── raw/ # 原始采集数据 │ └── processed/ # 清洗后的数据 ├── notebooks/ # 探索性分析ipynb ├── scripts/ │ ├── clean_data.py │ ├── feature_engineer.py │ └── visualization.py ├── output/ │ └── charts/ # 生成的HTML图表 └── requirements.txt依赖库方面只需要pandas、numpy、pyecharts、streamlit全部写在requirements.txt里换环境时一行pip install -r requirements.txt就搞定。不要一上来就上Spark、上数据库这个量级的分析单机Pandas绰绰有余。5. 核心图表实现四张图就够了5.1 价格分布直方图第一张图必看价格分布。用pyecharts的Bar组件把价格区间分成0-5万、5-10万、10-15万、15-20万、20-30万、30-50万、50万以上七档统计每个区间的车源数量。from pyecharts import options as opts from pyecharts.charts import Bar bins [0, 5, 10, 15, 20, 30, 50, float(inf)] labels [0-5万, 5-10万, 10-15万, 15-20万, 20-30万, 30-50万, 50万以上] df[price_bin] pd.cut(df[price_num] / 10000, binsbins, labelslabels, rightFalse) bin_counts df[price_bin].value_counts().reindex(labels) bar ( Bar() .add_xaxis(labels) .add_yaxis(车源数量, bin_counts.tolist(), color#2874A6) .set_global_opts( title_optsopts.TitleOpts(title二手车价格区间分布), yaxis_optsopts.AxisOpts(name车源数量), xaxis_optsopts.AxisOpts(name价格区间) ) ) bar.render(output/charts/price_distribution.html)这个图出来之后市场价格结构一目了然。我当时跑出来看10万以下的车源占比超过四成说明这个价位段竞争激烈车商收车压价有底气个人卖家在这个区间挂高价很难出手。5.2 车龄-价格散点图第二张图是车龄与价格的关系。画散点图时如果直接plot会有一堆重叠点看不出趋势。我的做法是加一个价格随车龄变化的趋势折线把每个车龄下的价格中位数连起来比单纯散点更直观。from pyecharts.charts import Scatter, Line from pyecharts.commons.utils import JsCode scatter ( Scatter() .add_xaxis(df[car_age].round(1).tolist()) .add_yaxis(价格(万元), (df[price_num] / 10000).round(1).tolist()) .set_global_opts( title_optsopts.TitleOpts(title车龄-价格散点趋势), datazoom_opts[opts.DataZoomOpts()], yaxis_optsopts.AxisOpts(name售价(万元)), xaxis_optsopts.AxisOpts(name车龄(年)) ) )加上缩放组件(datazoom)之后用户可以在页面上框选某个车龄区间放大看细节。这个交互在实际给车商朋友演示时非常加分比一句“车龄越长越便宜”有说服力得多。5.3 品牌平均价与保值率条形图第三张图是品牌维度的对比。把品牌按平均标价排序用条形图展示再用折线图在同一张图上叠加平均折价率双Y轴呈现。from pyecharts.charts import Bar, Line brand_df df.groupby(brand).agg( avg_price(price_num, mean), avg_depre(depreciation_rate, mean) ).sort_values(avg_price, ascendingTrue) bar ( Bar() .add_xaxis(brand_df.index.tolist()) .add_yaxis(平均标价(万元), (brand_df[avg_price] / 10000).round(1).tolist()) .set_global_opts( title_optsopts.TitleOpts(title品牌平均标价与保值率), yaxis_optsopts.AxisOpts(name平均标价(万元)) ) ) line ( Line() .add_xaxis(brand_df.index.tolist()) .add_yaxis(平均折价率(%), (brand_df[avg_depre] * 100).round(1).tolist()) )双Y轴一个轴表示价格一个轴表示折价率越低越保值。图一出来就能一眼分出“秒贬值车型”和“保值神车”。我自己看完这张图后的动作是以后换车优先考虑保值率前五的品牌卖车时不至于被刀太狠。5.4 城市热力地图第四张图是地域分布。如果数据有城市字段用pyecharts的Map组件按省份聚合车源量和均价。from pyecharts.charts import Map province_df df.groupby(province).size().reset_index(namecount) map ( Map() .add(车源量, [list(x) for x in province_df.values], china) .set_global_opts( title_optsopts.TitleOpts(title二手车车源量省份分布), visualmap_optsopts.VisualMapOpts(max_province_df[count].quantile(0.95)) ) ) map.render(output/charts/province_map.html)注意visualmap的max值如果直接用最大值少量热点省份会把色阶拉得极不均匀大多数省份会变成一个颜色。用分位数做上限地图的信息量会大很多。这点在用地图表达数据时特别重要。6. 打包交付与后续扩展心得6.1 项目如何组织成可交付的压缩包做这类项目最后的交付形式往往是一个压缩包。交付时不能直接把整个运行环境塞进去没人愿意收一个几百MB的文件夹。我的做法是代码、数据样例、使用说明三件套放根目录依赖列表用requirements.txt独立管理README里写清楚“如何安装依赖、如何跑脚本生成图表、输出在哪个目录”。这样即使对方完全不了解项目也能照着文档一步步跑通。还有个小细节如果你用的是Python虚拟环境打包前一定要记录好依赖版本尤其是pandas和pyecharts这两个库大版本之间API差异不小版本不锁死读者换环境后很容易跑挂。锁版本的方式很简单在虚拟环境里执行pip freeze requirements.txt即可。6.2 想做成网页版Streamlit 是最快路径静态HTML图表适合展示报告但如果想让你自己或者朋友能输入筛选条件、点按钮刷新结果我推荐用Streamlit搭一个轻量网页壳子。它能直接读取Pandas DataFrame配合pyecharts的components模块把图表嵌进网页代码量不大但交互体验提升明显。import streamlit as st from pyecharts.components import Table from streamlit_echarts import st_echarts st.title(二手车交易分析) brands st.multiselect(选择品牌, df[brand].unique().tolist()) filtered df[df[brand].isin(brands)] if brands else df st.metric(车源总量, len(filtered))老实说Streamlit这种“用Python写界面”的模式并不是全能但做内部工具或毕业设计级别的交付物完全够用。我在自己的项目里用它加了一个价格筛选滑条演示时效果比静态图表好很多。6.3 后续还能加什么整个系统跑通之后我后续还做了三件扩展一是加了个简单的线性回归模型用车龄、里程、品牌做价格预测准确率在75%左右作为参考够用二是接上了定时任务每周自动拉一次新数据把图表重新生成一遍三是把输出目录挂到本地静态服务器上手机也能随时查看图表。如果想继续深入还可以往两个方向走一个是NLP方向分析车源描述文本里的高频关键词如“原版原漆”“全程4S店保养”“女士一手车”与价格的关系另一个是时序方向对热门车型的车源量和均价做时间序列趋势预测判断出手时机。我做这套系统的最大体会是不要一开始就追求大而全的技术栈把一小套数据跑通、把几个核心问题用图回答出来比套十个炫酷框架都有用。拿到一个压缩包项目搞清楚它要回答什么问题、数据从哪里来、怎么变成可靠的表格、哪几张图能直击要害这才是数据分析里最值钱的能力。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询