☰
2019-2025年地级市逐月新房房价数据集整理与Shp挂接指南
2026/10/15 16:18:22 网站建设 项目流程

做城市研究的朋友经常找我要同一类东西:地级市层面的逐月新房房价。听起来像查表一样简单,真正开工后才会发现问题一个接一个:有的城市某个月没数据,有的城市悄悄换了统计口径,有的城市连名字都改了。我前后花了两三周反复核对,最终整理出一套覆盖2019年到2025年的地级市逐月新房房价数据集,同时提供Excel表格和Shp矢量图层两种形态。这篇文章把整理思路、字段设计、清洗规则和挂接方法完整拆开来讲,给后面要碰这活儿的人省点时间。

整套数据的规模大概是这样的:覆盖全国三百个左右地级行政区,时间跨度从2019年1月到2025年5月,按月一条记录,Excel长表大约两万五千行。这个规模说大不大,说小也不小,但真正值钱的地方在于"对齐"——所有城市的月度口径、行政区划版本、空间底图基准都统一了。下面按我的实操顺序,逐个环节讲清楚。

1. 动手之前,先钉死"城市"和"价格"这两个定义

1.1 地级市的范围:市辖区还是全市

同样是"某地级市新房均价",A平台给你的可能是市辖区口径,B平台给你的可能是包含下辖县市的全市口径,两者在同一座城市能差出两千多块钱。原因不复杂:市辖区是城市核心城建区,新房供应和成交结构几乎全是高层商品房;一旦把下辖县市加进来,周边乡镇的低价盘会直接把均价拉低一大截。

我做的第一个决定是统一采用市辖区口径。理由有两个:第一,在"市辖区"这个空间单元上,官方和市场的覆盖度都最高,绝大多数城市都能查到连续月度值;第二,研究城市房价时,市辖区比全市更能反映城区供需,跨城市比较的噪音也小。当然,如果你做的是省域统筹之类的分析,用全市口径也完全合理,但必须全数据集保持一致,绝对不能今天用市辖区、明天用全市。

口径反映的内容数据获得难度跨城市可比性典型应用场景
市辖区城区新房成交情况相对容易较好城市横向比较、城区供需分析
全市(含下辖县市)全域均价相对难较差省域统筹、区域差异概览

1.2 新房均价从哪来:成交均价比挂牌价更接近真实

第二件事是搞清"新房均价"这四个字的数据来源。市面上的房价数据大体分两类。一类是实际成交均价,来自官方月度销售数据里的"销售金额÷销售面积",也就是把当月真实网签金额除以网签面积,这是所有口径里最接近市场真实温度的;另一类是房产信息平台上的新盘挂牌价,本质是销售方希望的报价,不是最终成交价。两类数据在城市间的覆盖率、更新节奏都不一样。

我的处理原则是:能反算成交均价的城市,一律用成交均价;实在拿不到的城市,才用房产信息平台的月度挂牌价补位,同时在source字段里把每条记录标清楚。这样做的好处是,做严谨分析的人可以按source过滤,只保留同一来源的数据;做快速扫描的人也可以放心用,至少知道哪一段是硬数据、哪一段是参考数据。两种来源混在一起用,最容易出问题,所以在数据结构上必须留一个可过滤的字段。

1.3 Excel是长表还是宽表:我两个都做了

Excel部分面临一个经典选择题:长表还是宽表。我最后的选择是都做,但分工不同。交付的Excel主表是长表——每一行是一个"城市×月份",字段固定为:城市编码、城市名、省份、年份、月份、均价、环比、同比、数据来源。长表配透视表非常顺手,筛选城市、画折线图、按区域汇总都方便,两万五千行左右的数据量,Excel跑起来毫无压力。

另外我还会提供一个宽表sheet,每个城市一行,把2019M01到2025M05这些月份打成几十列,专门给做相关性分析和热力图的人用。宽表不参与更新,我维护长表后写个小脚本自动转成宽表sheet,绝不手改,否则两份表一定会对不上。下面这段就是最常用的转换逻辑,用Python几行搞定:

import pandas as pd df = pd.read_excel("house_price_long.xlsx") # 长表 wide = df.pivot_table( index=["city_code", "city_name", "province"], columns="year_month", values="price", aggfunc="first" ).reset_index() wide.columns = [str(c) if str(c).startswith("2") else c for c in wide.columns] wide.to_csv("house_price_wide.csv", index=False, encoding="utf-8-sig")

Excel长表的核心字段设计如下,字段名尽量直白,让别人拿到就能看懂:

字段名类型说明
city_code文本12位行政区划代码,全表主键
city_name文本城市名称,展示用
province文本所属省份
year / month数值年份与月份
year_month文本形如2019M01,方便排序筛选
price数值新房月度均价(元/平方米)
mom / yoy数值环比涨跌幅、同比涨跌幅(%)
source文本数据来源类型,便于过滤
cur_flag文本行政区划基准版本标记

2. 清洗这活儿,比采集更占时间:四个我踩过的坑

2.1 城市名会变,12位代码才认人

我最先遇到的问题是城市名称的漂移。某地级市前年还在用老名字,去年改成新名字;有的城市因为行政区划调整,干脆从统计名单里消失。人眼能看出是同一个地方,但Excel的VLOOKUP看不出。所以整套数据的主键我用12位行政区划代码,城市名只当展示字段。但凡涉及范围变化,我会在数据集里加一个cur_flag,标明"当前序列以哪一年的行政区划为准",避免把调整前后的两段序列当成同一个东西硬拼。

这里有个容易被忽略的细节:12位代码在Excel里经常被自动转成科学计数法,比如显示成1.23E+11,直接用它去关联Shp必死无疑。我的办法是导出时强制把city_code列设为文本格式,所有下游处理都先做一次astype(str).str.strip(),把空格和不可见字符清干净,再做匹配。

2.2 缺月:宁标NA,不随手插值

一个城市某个月没数据,这类情况太常见了。有的北方城市冬季网签基本停更,也有的平台源干脆断档。我一开始尝试过用线性插值把缺月补上,后来发现行不通——房价序列的季节性很强,1月到2月之间插出来的平滑值,和3月真实成交的差异远大于随机误差。最后我妥协了:缺月一律标NA。计算环比和同比时,单月缺失就当不可比;连续缺两三个月,就直接看同比,不要硬算环比。

缺失情况处理规则
单月缺失标NA,环比口径标记为不可比
连续缺2—3个月不插值,优先观察同比序列
结构跳变月保留原值,加monitor标记
特殊口径合并月份单独用口径字段标注,排除出环比计算

2.3 单月跳涨25%:别急着当异常值删掉

我在核对时撞到过一座城市单月均价上涨接近25%的情况。第一反应是数据错位,追下去才发现那个月当地有几个高价改善盘集中网签,把成交均价一把拉上去了。这种结构性跳变是真实发生的,不是录入差错。我的处理方式很明确:原值保留,同时加一个monitor标记,提示使用者"这里可能是结构性因素,不是平滑的市场波动"。直接把数字抹掉,或者顺手改成前后平均,都会毁掉后续断点识别类分析的信息基础。

做数据的人要分清"错误值"和"真实极值":错误值来自录入错位、口径切换,必须修正;真实极值来自市场结构变化,必须保留。我见过太多人一上来就把波动超过20%的样本全部删掉,结果做出来的模型反而把正常市场周期当成了噪声。正确顺序是先查原始单据,确认不是录入问题,再决定怎么处理。

2.4 撤市设区、整体并入:范围变了,序列要谨慎拼接

第二种更麻烦的情况是城市范围变化。有的城市把旁边的县市并进市辖区,有的城市本身被并入另一个城市。2019到2025年这几年间,做过这类调整的城市不止一两个。我的对齐策略是:以2022年行政区划作为基准参考,当年以前的数据标记为旧范围,当年以后的数据标记为新范围。纵向做趋势图时要避免跨范围拼接,横向做空间分布图时也要注意面积变化导致的可视化错觉。

具体到操作上,我会为这些城市单独建一个调整记录表,写清楚调整月份、调整类型、涉及的旧城市编码和新城市编码。这份记录表不放进主数据,但会随数据集一起交付。为什么?因为别人拿到数据后如果发现某个城市序列断了,他需要这份记录来判断应该怎么接,而不是自己去翻地图猜。

3. Shp挂接:从Excel表格到能做空间分析的矢量图层

3.1 底图选基准年版,别用最新版

要把房价数据变成Shp,首先得有一份全国地级市级别的面要素底图。这份底图本身不含房价,但它是所有空间操作的骨架。我常用的方案是选2022年版的市级行政区划面,而不是最新版。原因很简单:如果用2019年的底图,后面新设的市落不上去;如果一味用最新版,最早年份有些已经撤并的城市会被人为画出一块额外面积。基准年版选在时间序列中间位置,效果通常最好。

底图还需要确认坐标系。我自己习惯统一用WGS84地理坐标系,投影转换的事留给使用者在自己的GIS环境里做。如果你打算直接用国内在线底图叠加,可能需要转换成对应的投影坐标系,这个在交付说明里写清楚就行,别让拿到数据的人自己去猜。

3.2 属性表的两种组织方式:宽表给时间滑块,长表给逐帧出图

Shp文件的属性表是dBase格式,字段名有历史包袱,只支持10个字符以内的ASCII字段名,中文更是别想。所以我的月份字段统一用2019M01、2019M02这种写法。属性表我提供两种组织方式。

第一种是宽表,每个城市一行,几十个月份各占一列。桌面GIS软件做时间滑块动画时,可以直接把这几十个字段指认为时间序列字段,逐月播放,不需要预处理。这里有个细节:月份字段最好统一存成文本类型,不要存成数值或日期,否则软件读入时可能自动转换,导致字段名和实际序列错位。

第二种是长表,城市面要素按月份重复出现,每次携带year_month和price两个关键字段。优点是按月份筛选、导出单月数据非常痛快,缺点是文件体积膨胀,两三万个多面要素,老机器打开会有点吃力。我两个版本都生成,常规交付默认用宽表,按需再给长表。

3.3 Join才是最容易翻车的地方

把Excel连上Shp属性表,本质是一场join。很多人图省事直接按城市名join,会踩两个坑:一是城市改名导致部分行匹配不上,二是字段里夹杂空格、特殊符号导致显示一致但实际不一致。我的连接键永远是12位行政区划代码。具体操作是先把底图属性表里的city_code转成文本、去空格,再把Excel里的city_code做完全一样的清洗,最后join。我用一个小脚本完成这套动作:

import geopandas as gpd import pandas as pd gdf = gpd.read_file("city_base_2022.shp") # 底图 df = pd.read_excel("house_price_wide.xlsx") # 宽表房价 gdf["city_code"] = gdf["city_code"].astype(str).str.strip() df["city_code"] = df["city_code"].astype(str).str.strip() merged = gdf.merge(df, on="city_code", how="left") print("底图要素数:", len(gdf)) print("匹配后带属性要素数:", merged["price_2019M01"].notna().sum())

join完必须做两个检查:原图要素数是多少,join后带属性要素数是多少,两个数不一致说明有城市没匹配上。我遇到过两座城市的代码因为末尾补零位数不统一而匹配失败的情况,肉眼完全看不出,全靠计数检查揪出来。另外,Shapefile的join关系本质是动态的,源数据更新后需要重新跑;如果要交付给合作者,我通常直接把join完成的副本另存为一个全新的Shp文件,而不是留一个"自己跑一下脚本"的半成品。

4. 用这套数据,我实际做过的四类分析

4.1 时序曲线:先处理季节口径,再谈趋势

拿到长表Excel,第一步通常是画每个城市的均价走势。这里有个很容易被忽略的地方:同比、环比这类序列对口径特别敏感。以月度绝对均价为例,1月经常有返乡置业小高峰,2月叠加春节因素,个别年份官方甚至会把1—2月合并发布。这几个时点都不适合直接和其他月份对比。我自己的做法是在数据里增加一个cal_note字段,标注哪些月份是口径特殊月,画环比图时直接把特殊月排除,免得曲线图上出现莫名其妙的尖峰。

同比计算则需要当前月对应12个月之前的同城数值。长表里用筛选加排序就能轻松完成,宽表虽然画图方便,想做同比还得切回长表处理。这也是我坚持维护长表为主的原因——分析工作绝大多数是在长表上完成的。

4.2 截面分级:自然断点比等距分箱靠谱

画某一时点的全国房价分布,第一步是给均价分层。新手习惯用等距分箱,比如每5000元一档,画出来之后东部沿海一堆深色,中西部全是浅色,信息几乎被压缩没了。更合理的方案是用自然断点法,让每一档内部的差异尽量小、档与档之间的差异尽量大。我实测下来,用0—6000、6000—12000、12000—20000、20000—30000、30000以上这五档,叠上城市排名四分位,既有层次又能保留细节。

分析类型推荐数据格式关键字段
时序趋势Excel长表price、yoy、mom
截面分布Shp宽表或长表指定月份字段
空间自相关Shp宽表 + 邻接矩阵city_code
动画地图Shp宽表 + 固定图例全月份字段

4.3 空间自相关:邻接矩阵别让岛城没有邻居

做莫兰指数分析时,得先构建地级市之间的邻接关系。直接使用默认的公共边界相邻,沿海的岛市会出现没有邻居的情况,最后需要手动给它们补一条到最近大陆城市的连接。城市面积差异大也会干扰结果——面积特别大的西部城市,邻接数量动辄七八个,而东部密集区的城市可能只有三四个,空间权重矩阵的稳定性会受影响。我的建议是:做空间自相关前,把面积特别大的几个西部城市单独检查一遍;如果邻接权重结果不稳定,改用k近邻权重再跑一次,通常更稳健。

这一节最容易被低估的是"邻接关系"本身也是一种数据。我第一次算莫兰指数时,直接用了软件默认生成的空间权重,结果局部显著性的聚集区都集中在面积最大的那几个城市周围,后来才发现是权重矩阵被少数城市带偏了。换了k近邻之后,结论才合理。

4.4 动画地图:固定图例范围,别让颜色乱跳

2019到2025年逐月变化,很适合做成动画地图。新手最容易犯的错,是让GIS软件每一帧自动计算图例范围。结果是价格低的月份整张图浅色,价格高的月份整张图深色,观众只看到颜色忽明忽暗,空间差异完全看不出来。正确做法是先算出全部时间段的最小值和最大值,手工指定固定分级,比如上面那五档一直不变,再逐帧出图。这样动画里的颜色深浅,才能真实反映不同城市在不同年份的空间分化。

出图时还有一个细节:每一帧的标题尽量带上具体月份,比如2020M05,否则动画播放起来,观众根本不知道自己在看哪个时点。如果是导出GIF或视频,建议每帧保持同样的地图范围和背景透明度,避免视觉跳动。

5. 交付数据时,我会额外配齐这几样东西

5.1 META表:版本、来源、口径一键可查

整理得再干净,没有版本说明也等于白做。我每次更新完,会在Excel第一张sheet放一张META表,写清楚:数据抓取日期、来源渠道、口径定义(市辖区还是全市)、覆盖城市数、起始结束月份、本次更新内容。这个习惯救过我很多次——半年后你自己都可能忘掉这批数据是怎么来的,更别说合作者。META表不需要很长,三五行字,但一定要承诺它跟当前数据是同步的,否则等于没写。

5.2 Shp包里一定要有readme.txt

Shp文件看起来是一个文件,实际上是一组;除了.shp、.dbf、.shx、.prj这些核心组件,我还会额外放一个readme.txt,里面就三句话:坐标系是什么、底图基准是哪一年、字段命名规则是什么。很多人拿到Shp第一件事就是叠底图查位置,坐标系不写清楚,整个图层都会错位;有过一次教训之后,我现在宁可多写几句,也不让对方瞎猜。readme里还可以补一句"所有数据为公开渠道整理,仅供研究参考",把自己的责任边界划清楚。

5.3 source字段不能删,混合来源要明说

这套数据里,source字段的意义远大于"数据来源"四个字。官方统计和市场平台的口径先天不同,做严谨回归的人会按source过滤,只保留下同一口径的样本;做泛读报告的人会全部混用。所以我在交付说明里通常加一句:跨来源的数据只能用于描述整体量级和变化趋势,不适合做城市间的精确排名。这不是免责声明,而是这套数据真实的能力边界。使用者如果非要排名,我建议他先看source=同一种来源的子集,再看结果。

最后讲一点个人体会。整理这类时空数据,最难的不是采集,而是让每一行数据都能被追溯、被解释。你很难保证所有城市所有月份的数值都百分之百准确,但只要来源字段、口径字段、异常标记都清清楚楚,拿数据的人就能自己判断哪些能用、哪些要谨慎。这比我拍着胸脯保证"绝对准确"更实在。这套2019—2025年的地级市逐月新房房价数据我后续还会按季度更新,打算补上省级汇总和城市群维度的衍生指标,如果你有特殊需求,欢迎留言交流。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询