我用 Python 做了一个国内城市排行

2,274 阅读10分钟

Figure_1.png

1、背景

“城市化”这个熟悉又陌生的名词,影响着一代又一代人。伴随着城市化的城市选择,对于“新声代农民工”来说,无异于一次新的人口迁徙。城市的选择会影响接下来几代人的生活。由此,城市选择的重要性可见一斑。

对于宜居城市排名,现在市面上流行的方案的普遍问题是:

  1. 排名过程中考虑的因素太少,并不能满足城市选择的需求。 比如,华顿经济研究院编制发布的 中国百强城市排行榜 只考虑了经济和非经济 (软经济) 两个方面的因素,并不涉及气候、医疗、交通等信息。

  2. 城市的排名是个性化的,当前的方案无法满足用户个性化的需求。 比如,月收入在 1 万以内和 3 万以上的人对房价均价在 3 万以上的城市评分应是不同的。

因此,相对于一般的城市排名,我们的排名的优势在于:

  1. 将更多的信息被纳入考量。我们考虑的因素包括经济、医疗、财政、城建、气候、交通、就业、房价和共 9 项。

  2. 允许用户对各项因素设置不同的权重,以满足个性化的需求

该项目的宗旨就在于综合考虑各项重要因素,帮助用户个性化地选择适合自己定居的城市。

2、方案设计

2.1 总得分计算方式

如上所述,我们的方案中考虑的因素包括经济、医疗、财政、城建、气候、交通、就业、房价和教育 9 项。在我们的方案中最终的总分是各项数据得分乘以权重的和,即

P总分=PipiP_{总分} = \sum P_{i}*p_{i}

其中

  1. PiP_{i} 分别是经济、医疗、财政、城建、气候、交通、就业、房价和教育的各项的得分
  2. pip_{i} 分别是经济、医疗、财政、城建、气候、交通、就业、房价和教育的各项的权重

对于每一项因素,计算的逻辑是,

P得分=(eEmin)/(EmaxEmin)P_{得分} = (e - E_{min}) / (E_{max} - E_{min})

其中,

  • P得分P_{得分} 代表这项因素的得分
  • EminE_{min}EmaxE_{max} 分别代表该项因素的最小值和最大值
  • ee 代表该城市这项因素的值

以下是其中各项的具体计算逻辑。

2.3 每项指标及其含义

对于上述每项指标的选择原因是,

  • 首先,经济状况反映一个城市的经济活跃度,是一项重要指标
  • 其次,作为压在普通人头上三座大山的医疗、教育和房子是另外三项重要指标
  • 财政状况用来反映一个城市未来的服务水平
  • 城市建设指的是城市的体育、文化和绿地面积建设水平,反映一个城市的基本面貌
  • 就业是当地工作的收入水平
  • 交通是城市内的公共汽车和出租车的状况,用来反映出行是否便利

2.4 数据来源和采集过程

我们方案的数据来自:

  • 历年的城市统计年鉴
  • 各个地方的城市统计年鉴以
  • 网站上收集来的房价、气候和空气质量质量等信息

你可在参考文献中了解我们使用的数据来源。

3、方案实现

3.1 以经济指标为例,单一指标的评分逻辑

对于经济因素,参考的指标包括生产、消费和进出口三项。如下表格所示,其中的括号内的内容表示该子指标在经济因素中的权重。

指标及其权重子指标及其权重
生产 (1/3)GDP 总量得分 (1/9)
人均 GDP 得分 (1/9)
GDP 增长率得分 (1/9)
消费 (1/3)社零得分 (1/6)
人均社零得分 (1/6)
进出口 (1/3)进口得分 (1/6)
出口得分 (1/6)

由此可得,经济得分的计算公式,

P经济=(P生产+P消费+P进出口)/3P_{经济} = (P_{生产} + P_{消费} + P_{进出口}) / 3

其中,

  • P生产=PGDP总量+P人均GDP+PGDP增长率P_{生产} = P_{GDP 总量} + P_{人均 GDP} + P_{GDP 增长率}
  • P消费=P社零+P人均社零P_{消费} = P_{社零} + P_{人均社零}
  • P进出口=P进口+P出口P_{进出口} = P_{进口} + P_{出口}

计算代码,

def calculate_economic_grades(datas: Datas) -> Dict[str, Grades.Economic]:
    """计算城市的经济评分"""
    economics = {}

    # 计算均值
    for city, retail in datas.total_retail_sales_and_wholesales.items():
        population = datas.populations.get(city)
        retail.calculate_per_capita(population)

    # 生产总值
    grp_total_max = max([grp.total for grp in datas.gross_regional_products.values() if grp.total != ''])
    grp_total_min = min([grp.total for grp in datas.gross_regional_products.values() if grp.total != ''])
    grp_per_capita_max = max([grp.per_capita for grp in datas.gross_regional_products.values() if grp.per_capita != ''])
    grp_per_capita_min = min([grp.per_capita for grp in datas.gross_regional_products.values() if grp.per_capita != ''])
    growth_rate_max = max([grp.growth_rate for grp in datas.gross_regional_products.values() if grp.growth_rate != ''])
    growth_rate_min = min([grp.growth_rate for grp in datas.gross_regional_products.values() if grp.growth_rate != ''])
    # print("grp max[%f] min[%f] per max[%f] per min[%f]" % (grp_total_max, grp_total_min, grp_per_capita_max, grp_per_capita_min))
    for city, grp in datas.gross_regional_products.items():
        economic = Grades.Economic()
        if grp.total != '':
            economic.grp_total_grade = (grp.total - grp_total_min) / (grp_total_max - grp_total_min)
        if grp.per_capita != '':
            economic.grp_per_capita_grade = (grp.per_capita - grp_per_capita_min) / (grp_per_capita_max - grp_per_capita_min)
        if grp.growth_rate != '':
            economic.growth_rate_grade = (grp.growth_rate - growth_rate_min) / (growth_rate_max - growth_rate_min)
        # print('%s %s' % (city, economic))
        economics[city] = economic
    
    # 社零
    retail_sales_max = max([trs.retail_total for trs in datas.total_retail_sales_and_wholesales.values() if trs.retail_total != ''])
    retail_sales_min = min([trs.retail_total for trs in datas.total_retail_sales_and_wholesales.values() if trs.retail_total != ''])
    retail_sales_per_capita_max = max([trs.retail_total_per_capita for trs in datas.total_retail_sales_and_wholesales.values() if trs.retail_total_per_capita is not None])
    retail_sales_per_capita_min = min([trs.retail_total_per_capita for trs in datas.total_retail_sales_and_wholesales.values() if trs.retail_total_per_capita is not None])
    for city, trs in datas.total_retail_sales_and_wholesales.items():
        economic: Grades.Economic = economics[city]
        if trs.retail_total != '':
            economic.total_retail_sales_grade = (trs.retail_total - retail_sales_min) / (retail_sales_max - retail_sales_min)
        if trs.retail_total_per_capita is not None:
            economic.total_retail_sales_per_capita_grade = (trs.retail_total_per_capita - retail_sales_per_capita_min) / (retail_sales_per_capita_max - retail_sales_per_capita_min)

    # 进出口
    export_max = max([fte.export_of_goods for fte in datas.foreign_trade_and_economic_cooperations.values() if fte.export_of_goods != ''])
    export_min = min([fte.export_of_goods for fte in datas.foreign_trade_and_economic_cooperations.values() if fte.export_of_goods != ''])
    import_max = max([fte.import_of_goods for fte in datas.foreign_trade_and_economic_cooperations.values() if fte.import_of_goods != ''])
    import_min = min([fte.import_of_goods for fte in datas.foreign_trade_and_economic_cooperations.values() if fte.import_of_goods != ''])
    for city, fte in datas.foreign_trade_and_economic_cooperations.items():
        economic: Grades.Economic = economics[city]
        if fte.export_of_goods != '':
            economic.export_of_goods_grade = (fte.export_of_goods - export_min) / (export_max - export_min)
        if fte.import_of_goods != '':
            economic.import_of_goods_grade = (fte.import_of_goods - import_min) / (import_max - import_min)

    # 计算最终得分
    for economic in economics.values():
        economic.calcualte()

    return economics

由于后续每项的计算逻辑与经济类似,因此只给出具体的参考因素和得分。

3.2 其他指标的评分和权重

1. 医疗各项指标及其权重

指标及其权重子指标及其权重
医生 (1/2)医生总量 (1/4)
人均医生 (1/4)
床位 (1/2)床位总量 (1/4)
人均床位 (1/4)

注意,其中的人均数值是使用医生或者床位的总量除以当地户籍总人口所得。在每项指标中,人均和总量权重分别为 0.5 以减少人口数量过多导致总量较大的问题。以下几项指标的计算逻辑相同。

2. 财政各项指标及其权重

指标及其权重子指标及其权重
一般公共预算结余 (1/2)
一般公共预算结余占一般公共预算收入的比 (1/2)

一般公共预算结余的计算方式是,

G一般公共预算结余=G一般公共收入G一般公共预算支出G_{一般公共预算结余} = G_{一般公共收入} - G_{一般公共预算支出}

3. 城建各项指标及其权重

指标及其权重子指标及其权重
绿地面积 (1/2)绿地面积总量 (1/4)
人均绿地面积 (1/4)
文化设施 (1/2)图书馆馆藏总量 (1/6)
图书馆人均馆藏量 (1/6)
博物馆数量 (1/6)

4. 气候各项指标及其权重

指标及其权重评分标准
降水量 (1/5)每个月降水量在 50 至 150 毫米则满分 1,降水量低于 50 或者高于 150 的,每低或者高 1 毫米计分减少 1/50 分,减至 0 为止
平均气温 (1/5)每个月平均气温在 15°C 到 25°C 之间则满分 1,低于 15°C 或者高于 25°C 的时候,每低或者高 1°C 计分减少 1/15 分,减至 0 为止
日照时间 (1/5)每天大约 8 到 10 小时的日照时间时计为满分 1 分,每增加、减少 1 小时,计分减少 1/6 分,减至 0 为止
相对湿度 (1/5)湿度应该在 40% 到 60% 之间时满分 1,湿度低于 40% 或者高于 60% 的时候,每增加或者减少 1%,计分减少 1/40,减至 0 为止
空气质量 (1/5)API 小于等于 50 时则为满分 1,200 为 0 分,中间每增加 1,则减少 1/150 分

5. 交通各项指标及其权重

指标及其权重子指标及其权重
公共汽车总量 (1/2)
出租车总量 (1/2)

6. 就业各项指标及其权重

指标及其权重子指标及其权重
就业机会 (1/2)城镇非私营单位从业人员期末人数 (1/4)
城镇非私营单位从业人员期末人数除以当地户籍人口总数 (1/4)
工资收入 (1/2)城镇非私营单位在岗职工平均工资

需要注意的是,这里计算就业数据的时候采用的是城镇非私营单位企业员工的人数和平均工资。

7. 房价各项指标及其权重

指标及其权重子指标及其权重
房价 (1)

8. 教育各项指标及其权重

指标及其权重子指标及其权重
学校 (1/4)大学 (1/16)
中学 (1/16)
小学 (1/16)
专任教师 (1/4)大学专任教师总量 (1/32)
大学专任教师人均 (1/32)
中学专任教师总量 (1/32)
中学专任教师人均 (1/32)
小学专任教师总量 (1/32)
小学专任教师人均 (1/32)
在校生 (1/4)大学在校生总量 (1/32)
大学在校生人均 (1/32)
中学在校生总量 (1/32)
中学在校生人均 (1/32)
小学在校生总量 (1/32)
小学在校生人均 (1/32)
高校质量加分 (1/4)985 学校数量 (1/8)
211 学校数量 (1/8)
专利授权量 (1/2)

4、结果

以下是按照上述计算得出的总分前 100 位的城市,

排名城市总分经济医疗财政城建气候交通就业房价科教
1北京市82.670983.42100.0098.6674.6355.66100.00100.0014.33100.00
2上海市73.6121100.0091.5699.48100.0050.2056.5693.230.0051.86
3深圳市70.725786.0670.1599.5575.2072.7178.2185.172.8452.21
4广州市63.770754.7480.0596.2263.7168.3842.6967.3447.4849.76
5杭州市59.584541.9277.21100.0043.6594.7227.5862.3851.1234.90
6成都市58.337739.3781.4698.0149.1242.3335.8862.6476.6635.27
7南京市57.449346.8657.0899.6953.4978.6122.8157.2863.6837.72
8苏州市56.379870.6359.2999.8329.4278.5614.7756.6272.7125.35
9东莞市55.562451.0172.2199.0936.6467.082.7763.2670.9229.37
10重庆市55.325243.8671.1693.0041.5346.6840.4044.6989.1838.07
11武汉市54.562238.0564.9297.4737.1865.7430.2345.3282.0539.35
12西安市51.623822.8553.9395.4741.1667.6627.2244.1883.1036.49
13郑州市51.370828.3375.5197.9520.6471.1919.5740.2787.1432.85
14宁波市51.180242.2247.9799.2128.06100.0013.6247.9969.0615.68
15天津市51.169228.1548.9297.0433.5555.3646.5650.4675.9725.22
16济南市50.348927.4256.4598.2330.2375.8022.0243.3482.2024.46
17青岛市49.812038.4750.3598.4617.0179.5722.2344.7079.5723.08
18长沙市48.818130.2557.8198.1414.8058.7222.8942.1789.7031.52
19合肥市48.261930.1346.8697.1918.3181.7219.9941.8479.4325.31
20昆明市48.037718.3362.4197.8315.4081.3218.0538.9988.2420.81
21无锡市47.333836.7447.7699.1925.8271.617.9044.3582.2513.36
22沈阳市46.183819.5758.6597.9017.2161.4426.6135.6092.1217.12
23佛山市45.683232.7744.6897.9613.7567.7313.5242.3783.1018.58
24太原市45.651218.8665.3396.9614.4466.0612.7036.6591.5417.32
25嘉兴市44.582624.6238.5998.9120.3389.022.8340.1182.468.85
26贵阳市43.865216.7352.3296.448.7054.6720.7739.3094.0616.36
27温州市43.846620.1936.6296.1021.6989.027.9037.4778.4413.57
28常州市43.550231.0235.2699.2515.2571.616.6240.2784.0311.91
29大连市43.495119.7243.6497.9519.0961.4418.0136.8486.3015.12
30绍兴市43.420524.4632.7098.8619.0389.025.0037.1280.6210.28
31珠海市43.378125.0638.9195.2630.5248.256.6750.9071.3016.02
32舟山市42.887121.0327.9094.6026.0789.021.8339.3885.703.96
33湖州市42.494020.2533.7498.3314.4989.022.5735.6189.385.95
34烟台市42.378425.1931.9598.4916.7575.806.6032.2093.7810.81
35金华市42.347424.8937.7496.1911.6889.022.2736.3877.7711.15
36潍坊市42.213017.7638.0797.8819.2175.804.5629.2496.2914.07
37长春市42.154212.9846.8796.4522.8239.7921.4334.0293.9119.24
38东营市41.977819.5630.7799.0712.5775.804.9336.6796.097.65
39南通市41.953528.4630.4796.3613.3071.615.4738.5785.7610.95
40淄博市41.953214.5435.2497.3923.7775.808.6030.5294.508.65
41台州市41.593518.8227.8496.1619.2589.023.8034.7880.8610.62
42洛阳市41.385711.4632.6696.1626.4181.078.2825.8794.3011.78
43福州市41.381029.9133.5598.5419.3551.8213.4439.7871.2616.36
44南昌市41.357821.1137.2395.0211.9653.9111.2137.5987.9320.02
45厦门市41.079834.9542.6298.7421.3251.8211.1048.9736.0516.27
46中山市40.681421.3640.7396.9114.8248.252.7740.0890.3211.48
47淮安市40.485215.9617.4293.327.3771.613.6847.0993.637.66
48西宁市39.97138.9845.0492.256.1367.197.5736.1992.767.40
49徐州市39.949520.0428.6594.559.3871.617.1130.2091.6516.12
50石家庄市39.828112.0745.3295.669.8256.2312.8829.9186.8119.68
51济宁市39.730812.7331.8395.9214.8575.806.1726.9794.6211.44
52兰州市39.701613.6845.2995.2910.1442.4313.4334.9190.0816.85
53威海市39.662719.2429.1498.2111.5775.803.7528.1195.367.34
54临沂市39.651313.4829.9893.9115.5075.805.3227.4793.7013.88
55哈尔滨市39.50159.7149.7889.2520.5928.9124.7429.6893.3019.36
56芜湖市39.469121.1326.9197.548.2374.575.8630.3690.848.90
57攀枝花市39.224410.2535.3194.295.6829.142.1156.2298.124.93
58嘉峪关市38.982210.3748.1599.1619.0042.430.6633.1199.644.19
59呼和浩特市38.982013.0240.0494.7417.2345.689.5332.7992.1311.86
60南宁市38.945111.7338.8793.8210.9243.0710.9035.4691.1818.05
61克拉玛依市38.844917.2131.7498.1333.460.001.7349.7598.698.01
62唐山市38.668316.1837.8895.8211.0856.238.3429.0691.7611.26
63衢州市38.542212.0023.4086.437.1589.020.7738.9684.903.83
64惠州市38.486419.9726.7097.148.3448.254.7537.3591.4113.61
65泰州市38.264619.1621.4896.317.9571.612.7734.1889.275.73
66马鞍山市38.239515.8219.4497.118.1974.572.7232.3893.865.93
67扬州市38.137318.1721.3393.7810.1871.615.1034.0286.306.86
68鄂尔多斯市38.079921.1830.0197.9913.2145.682.6935.0593.196.76
69泉州市37.918831.6623.7897.9211.6051.823.5030.3983.4514.67
70盐城市37.785217.0323.2291.627.7071.613.8831.3491.778.33
71丽水市37.76429.9523.2485.378.3589.021.1639.1877.984.21
72榆林市37.733214.6819.6997.739.1877.211.4231.2888.156.70
73银川市37.491810.6840.9595.599.3632.217.1736.5895.5710.22
74滨州市37.082410.2324.8695.845.2875.800.7527.6396.576.25
75包头市37.023817.1038.2393.197.6845.686.4529.9195.816.27
76宜昌市37.008624.0827.9090.979.2659.022.6328.0395.594.57
77泰安市36.99557.4225.0294.6212.3375.805.0024.4492.578.30
78拉萨市36.959314.7332.0587.583.9927.471.8447.9488.7317.35
79连云港市36.913312.0917.2694.0810.7571.613.3930.1791.108.51
80黄山市36.880010.9618.0691.0722.5774.570.7226.6594.173.37
81南阳市36.82489.5628.2286.967.4381.073.4919.7696.2915.71
82绵阳市36.656212.0426.0187.875.9729.144.0349.3094.598.31
83延安市36.65569.0419.2788.8312.3077.211.7227.3397.246.29
84滁州市36.609114.0719.1594.734.5974.571.9527.0697.085.84
85德阳市36.492410.8820.8792.504.0529.141.3851.9297.005.27
86焦作市36.47356.3025.7795.705.5981.072.2020.7098.548.16
87三门峡市36.46718.9924.6595.243.9181.071.3022.8098.595.33
88平顶山市36.43387.3121.7195.895.1281.073.4421.1797.3010.15
89宜宾市36.417010.2520.9792.184.4129.142.6851.4695.755.86
90枣庄市36.41488.5321.4495.468.2775.802.8624.7794.917.33
91遵义市36.335810.1327.7288.295.3454.675.0732.0198.0910.04
92日照市36.30649.1418.7897.233.7675.802.7528.4893.195.45
93新乡市36.27986.5625.4993.014.6281.072.7320.0296.4612.83
94安阳市36.26134.3620.0794.576.7081.072.5422.2997.8210.90
95玉溪市36.257714.5222.7795.044.7862.812.3029.1897.234.77
96本溪市36.25664.8126.6494.9723.2061.443.1622.8999.423.15
97聊城市36.18107.0021.7992.988.0875.803.0824.7693.4310.13
98铜陵市36.17989.7816.5293.219.2774.572.2527.9196.803.58
99宝鸡市36.10938.7726.8982.179.5077.213.8824.1299.395.04
100大同市36.08397.5725.8092.197.8666.066.5225.7797.905.40

5、缺陷与改进

5.1 计算方式的问题

参考 3 中的计算方式,在不少地方计算的时候我们使用了人均和总量各 50% 比例来计算单一指标得分的方案。按照这种计算方式可能会导致某些人均资源占有量比较大的城市得分比较突出。比如,克拉玛依市仅 32 万人,导致人均资源占有量非常高;又比如东莞,以 2023 年统计数据为例,年末常住人口 1043.70 万人,而户籍人口仅为 292.45 万人,因此以户籍人口计算人均资源占有量就会使得整体熟知偏高。但是,若以常住人口计算人均资源又因为相关数据在各个城市的统计口径问题无法实现。

5.2 数据不足导致的问题

1. 数据缺失处理

极个别城市的个别数据因为没有统计导致出现缺失,比如东莞市的交通数据(公交和出租的数量)。对此,我们采用的处理方式是使用全部城市得分的中位数进行填充。这可能会导致计算的结果出现偏差。

2. 数据统计的限制

在上述计算过程中,我们仅计算了各地医疗资源的总量和人均占有量,并没有将医院的质量纳入计算过程,因此计算的结果会出现一定偏差。

在上述计算过程中,在计算中学和小学的过程中仅计算了各地教育资源的总量和人均占有量,没有将学校的质量纳入考评过程,因此计算的结果和会出现一定偏差。

在上述计算过程中,在对就业指标进行计算过程中,我们使用城镇非私营员工数量和收入水平进行统计,只能反应城镇非私营单位的就业状况,不能代表整体的就业水平。

在上述计算过程中,在对交通指标进行计算过程中,我们仅计算了城市内的公交车和出租车数量,没有计算轨道交通、铁路和航空等信息,与实际结果可能会出现一定偏差。

5.3 改进

针对数据不足导致的计算结果问题,应该收集更多数据以对医疗资源的质量、初等教育的质量和各行各业就业数据等进行分析。

如果你有任何疑问和建议可以与我们进行沟通,我们乐意听到你的意见和建议。

6、参考文献和资料

6.1 经济与社会数据

6.2 气候与环境数据

6.3 相关研究数据