首页 > 解决方案 > 根据python中的值溶解多边形

问题描述

我在 GeoPandas 数据框中有一长串多多边形(下面的示例),覆盖大面积

如您所见,每个多边形都有一个分配给它的值

import geopandas as gpd
import json
import numpy as np

geojs = """{"type": "FeatureCollection", "features": [
{"id": "N09000001", "type": "Feature", "properties": {"areaCode": "N09000001", "areaName": "Antrim and Newtownabbey", "lat": 54.693859, "long": -6.1776, "newCasesByPublishDate": 0, "pop_total": 143504.0}, "geometry": {"type": "Polygon", "coordinates": [[[-5.86825366596761, 54.6888687315215], [-6.42599769869378, 54.5682228227428], [-6.40709797647204, 54.6488262417787], [-6.49592646364251, 54.7136654189767], [-6.47705679588031, 54.7809040831338], [-6.17201760379953, 54.8118689593733], [-5.90078287621989, 54.7802879317437], [-5.86825366596761, 54.6888687315215]]]}}, 
{"id": "N09000011", "type": "Feature", "properties": {"areaCode": "N09000011", "areaName": "Ards and North Down", "lat": 54.564091, "long": -5.64568, "newCasesByPublishDate": 0, "pop_total": 161725.0}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-5.72240274893475, 54.6679350827123], [-5.53018929572445, 54.6449747684061], [-5.43278427013933, 54.4873271377048], [-5.4967641358556, 54.3332820510907], [-5.58374699641201, 54.4495151959215], [-5.83307469136698, 54.5013362048085], [-5.75746880588443, 54.5814493468674], [-5.8551033270334, 54.6336755747003], [-5.72240274893475, 54.6679350827123]]], [[[-5.52130681342862, 54.6763980619936], [-5.52451559144809, 54.6689614290521], [-5.54541862179215, 54.6728668110707], [-5.53399350908627, 54.6817324732442], [-5.52130681342862, 54.6763980619936]]]]}}, 
{"id": "N09000002", "type": "Feature", "properties": {"areaCode": "N09000002", "areaName": "Armagh City, Banbridge and Craigavon", "lat": 54.3867, "long": -6.43455, "newCasesByPublishDate": 0, "pop_total": 216205.0}, "geometry": {"type": "Polygon", "coordinates": [[[-6.30463487433425, 54.5728762162142], [-6.21018440507748, 54.4327414539901], [-6.02077672167709, 54.3775327812064], [-6.10439819657023, 54.3184829861156], [-6.05037829121797, 54.2439277962008], [-6.40166778884486, 54.2730345896177], [-6.74080426483726, 54.181913450597], [-6.8780191863648, 54.2790616644097], [-6.62945282074104, 54.5038182011799], [-6.30463487433425, 54.5728762162142]]]}}, 
{"id": "N09000003", "type": "Feature", "properties": {"areaCode": "N09000003", "areaName": "Belfast", "lat": 54.59853, "long": -5.92535, "newCasesByPublishDate": 0, "pop_total": 343542.0}, "geometry": {"type": "Polygon", "coordinates": [[[-5.91286240816905, 54.6479813159384], [-5.82317953443164, 54.5814831869039], [-6.05976859781416, 54.555167284957], [-5.98640654742133, 54.6594276520093], [-5.91286240816905, 54.6479813159384]]]}}, 
{"id": "N09000004", "type": "Feature", "properties": {"areaCode": "N09000004", "areaName": "Causeway Coast and Glens", "lat": 55.039619, "long": -6.5996, "newCasesByPublishDate": 0, "pop_total": 144838.0}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-6.45495074152445, 55.2390595834363], [-6.06222813377427, 55.1988810582343], [-6.06224944358356, 55.060088368511], [-5.97692873094826, 55.0562971809219], [-6.09797775132434, 54.983953663772], [-6.32375081377751, 55.010219215385], [-6.44819910576625, 54.9646462040108], [-6.42214599001138, 54.9167752683675], [-6.73812196794712, 54.9288064587593], [-6.91206365023906, 54.8203769331924], [-7.03884094349723, 54.8454958029207], [-7.16588224886383, 55.0339566845656], [-7.04171190861944, 55.053036339119], [-6.96592115068434, 55.1947570244943], [-6.45495074152445, 55.2390595834363]]], [[[-6.16976043857174, 55.3015780943379], [-6.18991594869723, 55.2584649530643], [-6.28609463639854, 55.2934492699155], [-6.23996271067179, 55.3120797201995], [-6.16976043857174, 55.3015780943379]]]]}}, 
{"id": "N09000005", "type": "Feature", "properties": {"areaCode": "N09000005", "areaName": "Derry City and Strabane", "lat": 54.80904, "long": -7.42064, "newCasesByPublishDate": 0, "pop_total": 151284.0}, "geometry": {"type": "Polygon", "coordinates": [[[-7.14703863785253, 55.0467238746553], [-7.03884094349723, 54.8454958029207], [-6.90290110925193, 54.7838179439778], [-7.70348193231686, 54.6084590729046], [-7.91386707249341, 54.6759515699246], [-7.54333131919409, 54.7426737975962], [-7.39144386228221, 55.0223467555791], [-7.14703863785253, 55.0467238746553]]]}}, 
{"id": "N09000006", "type": "Feature", "properties": {"areaCode": "N09000006", "areaName": "Fermanagh and Omagh", "lat": 54.385208, "long": -7.5271, "newCasesByPublishDate": 0, "pop_total": 117397.0}, "geometry": {"type": "Polygon", "coordinates": [[[-6.94000526652459, 54.7735862770319], [-7.0111483263911, 54.7179164458596], [-6.97451346801048, 54.5436738653106], [-7.36702055464399, 54.4375109968609], [-7.14224373046422, 54.2556213291848], [-7.27950622073253, 54.1223799982782], [-7.86024218460512, 54.2175535507195], [-7.86188555448805, 54.2934868663368], [-8.17748428228008, 54.4647764398753], [-7.44786902453267, 54.6409673671176], [-7.30571657531746, 54.7384979023887], [-6.94000526652459, 54.7735862770319]]]}}, 
{"id": "N09000007", "type": "Feature", "properties": {"areaCode": "N09000007", "areaName": "Lisburn and Castlereagh", "lat": 54.49752, "long": -6.03545, "newCasesByPublishDate": 0, "pop_total": 146002.0}, "geometry": {"type": "Polygon", "coordinates": [[[-6.04553272895948, 54.6058944496858], [-5.97574465599047, 54.5305881456644], [-5.75746880588443, 54.5814493468674], [-6.01854109355525, 54.3704780281283], [-6.21018440507748, 54.4327414539901], [-6.30463487433425, 54.5728762162142], [-6.04553272895948, 54.6058944496858]]]}}, 
{"id": "N09000009", "type": "Feature", "properties": {"areaCode": "N09000009", "areaName": "Mid Ulster", "lat": 54.552731, "long": -6.8889, "newCasesByPublishDate": 0, "pop_total": 148528.0}, "geometry": {"type": "Polygon", "coordinates": [[[-6.49989811582067, 54.918760235465], [-6.42599769869378, 54.5682228227428], [-6.83703223420254, 54.3355920356199], [-7.02907277361944, 54.4213258057242], [-7.15271951714404, 54.3352258818404], [-7.33442900956349, 54.3716834169155], [-7.36702055464399, 54.4375109968609], [-6.97451346801048, 54.5436738653106], [-7.0111483263911, 54.7179164458596], [-6.8866002529905, 54.8529973410418], [-6.49989811582067, 54.918760235465]]]}}, 
{"id": "N09000008", "type": "Feature", "properties": {"areaCode": "N09000008", "areaName": "Mid and East Antrim", "lat": 54.86462, "long": -6.14645, "newCasesByPublishDate": 0, "pop_total": 139274.0}, "geometry": {"type": "Polygon", "coordinates": [[[-5.86825366596761, 54.6888687315215], [-5.88743175006564, 54.7723941141063], [-6.0098435957095, 54.8000951269846], [-6.47705679588031, 54.7809040831338], [-6.50629295628445, 54.9082576713827], [-5.97692873094826, 55.0562971809219], [-5.99007301125635, 54.984514642232], [-5.68964873973087, 54.8037059110952], [-5.86825366596761, 54.6888687315215]]]}}, 
{"id": "N09000010", "type": "Feature", "properties": {"areaCode": "N09000010", "areaName": "Newry, Mourne and Down", "lat": 54.149529, "long": -6.08891, "newCasesByPublishDate": 0, "pop_total": 181368.0}, "geometry": {"type": "Polygon", "coordinates": [[[-5.51597184422536, 54.3243388640101], [-5.66018062367681, 54.2256146968], [-5.81438348807952, 54.2864800457757], [-5.89692617268467, 54.1047041619978], [-6.06272153791029, 54.0227361083666], [-6.29088218758648, 54.1126750153287], [-6.6689790287571, 54.0728072786138], [-6.59991188551696, 54.2189466982227], [-6.43909451680779, 54.2674826587056], [-6.05037829121797, 54.2439277962008], [-6.09841841649155, 54.3265633644304], [-5.82346793804335, 54.495410544066], [-5.58374699641201, 54.4495151959215], [-5.51597184422536, 54.3243388640101]]]}}]}"""

gdf = gpd.GeoDataFrame.from_features(json.loads(geojs))
# divide into regions that can be used in dissolve
gdf["region"] = np.select(
    [gdf["lat"].gt(55), gdf["lat"].lt(54.2), gdf["long"].lt(-7), gdf["long"].gt(-6)],
    ["N", "S", "W", "E"],
    "C",
)
# what's does it originally look like
gdf.plot(column="pop_total")
# dissovle to regions
gdfa = gdf.dissolve(by="region", aggfunc="sum")
# what does this look like ?
gdfa.plot(column="pop_total")

我正在尝试根据值合并/溶解相同的内容,以便仅当新多边形的总面积 <= 300K 时才会发生新的溶解多边形,因此理想情况下,此处的输出应将区域 C 拆分为 3 个子组和区域E 分成 2 个子组

是否有一些我可以添加到这个的参数,或者会有一些其他的技术

标签: pythonpandasgroupinggeopandas

解决方案


  • 您的示例数据并不能真正用于您所描述的操作。使用北爱尔兰几何、人口和 COVID 案例来证明
  • 如您所描述的那样使用dissolve(),并没有担心某些属性不能相加(longlat
  • 更容易通过可视化看到,因此提供了每个阶段的图
  • 更新为使用pandas cumsum()功能在每次人口超过 300K 时细分区域
  • 这将 C 分解为 3 个区域,将 E 分解为 2 个区域
import geopandas as gpd
import json
import numpy as np

geojs = """{"type": "FeatureCollection", "features": [
{"id": "N09000001", "type": "Feature", "properties": {"areaCode": "N09000001", "areaName": "Antrim and Newtownabbey", "lat": 54.693859, "long": -6.1776, "newCasesByPublishDate": 0, "pop_total": 143504.0}, "geometry": {"type": "Polygon", "coordinates": [[[-5.86825366596761, 54.6888687315215], [-6.42599769869378, 54.5682228227428], [-6.40709797647204, 54.6488262417787], [-6.49592646364251, 54.7136654189767], [-6.47705679588031, 54.7809040831338], [-6.17201760379953, 54.8118689593733], [-5.90078287621989, 54.7802879317437], [-5.86825366596761, 54.6888687315215]]]}}, 
{"id": "N09000011", "type": "Feature", "properties": {"areaCode": "N09000011", "areaName": "Ards and North Down", "lat": 54.564091, "long": -5.64568, "newCasesByPublishDate": 0, "pop_total": 161725.0}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-5.72240274893475, 54.6679350827123], [-5.53018929572445, 54.6449747684061], [-5.43278427013933, 54.4873271377048], [-5.4967641358556, 54.3332820510907], [-5.58374699641201, 54.4495151959215], [-5.83307469136698, 54.5013362048085], [-5.75746880588443, 54.5814493468674], [-5.8551033270334, 54.6336755747003], [-5.72240274893475, 54.6679350827123]]], [[[-5.52130681342862, 54.6763980619936], [-5.52451559144809, 54.6689614290521], [-5.54541862179215, 54.6728668110707], [-5.53399350908627, 54.6817324732442], [-5.52130681342862, 54.6763980619936]]]]}}, 
{"id": "N09000002", "type": "Feature", "properties": {"areaCode": "N09000002", "areaName": "Armagh City, Banbridge and Craigavon", "lat": 54.3867, "long": -6.43455, "newCasesByPublishDate": 0, "pop_total": 216205.0}, "geometry": {"type": "Polygon", "coordinates": [[[-6.30463487433425, 54.5728762162142], [-6.21018440507748, 54.4327414539901], [-6.02077672167709, 54.3775327812064], [-6.10439819657023, 54.3184829861156], [-6.05037829121797, 54.2439277962008], [-6.40166778884486, 54.2730345896177], [-6.74080426483726, 54.181913450597], [-6.8780191863648, 54.2790616644097], [-6.62945282074104, 54.5038182011799], [-6.30463487433425, 54.5728762162142]]]}}, 
{"id": "N09000003", "type": "Feature", "properties": {"areaCode": "N09000003", "areaName": "Belfast", "lat": 54.59853, "long": -5.92535, "newCasesByPublishDate": 0, "pop_total": 343542.0}, "geometry": {"type": "Polygon", "coordinates": [[[-5.91286240816905, 54.6479813159384], [-5.82317953443164, 54.5814831869039], [-6.05976859781416, 54.555167284957], [-5.98640654742133, 54.6594276520093], [-5.91286240816905, 54.6479813159384]]]}}, 
{"id": "N09000004", "type": "Feature", "properties": {"areaCode": "N09000004", "areaName": "Causeway Coast and Glens", "lat": 55.039619, "long": -6.5996, "newCasesByPublishDate": 0, "pop_total": 144838.0}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-6.45495074152445, 55.2390595834363], [-6.06222813377427, 55.1988810582343], [-6.06224944358356, 55.060088368511], [-5.97692873094826, 55.0562971809219], [-6.09797775132434, 54.983953663772], [-6.32375081377751, 55.010219215385], [-6.44819910576625, 54.9646462040108], [-6.42214599001138, 54.9167752683675], [-6.73812196794712, 54.9288064587593], [-6.91206365023906, 54.8203769331924], [-7.03884094349723, 54.8454958029207], [-7.16588224886383, 55.0339566845656], [-7.04171190861944, 55.053036339119], [-6.96592115068434, 55.1947570244943], [-6.45495074152445, 55.2390595834363]]], [[[-6.16976043857174, 55.3015780943379], [-6.18991594869723, 55.2584649530643], [-6.28609463639854, 55.2934492699155], [-6.23996271067179, 55.3120797201995], [-6.16976043857174, 55.3015780943379]]]]}}, 
{"id": "N09000005", "type": "Feature", "properties": {"areaCode": "N09000005", "areaName": "Derry City and Strabane", "lat": 54.80904, "long": -7.42064, "newCasesByPublishDate": 0, "pop_total": 151284.0}, "geometry": {"type": "Polygon", "coordinates": [[[-7.14703863785253, 55.0467238746553], [-7.03884094349723, 54.8454958029207], [-6.90290110925193, 54.7838179439778], [-7.70348193231686, 54.6084590729046], [-7.91386707249341, 54.6759515699246], [-7.54333131919409, 54.7426737975962], [-7.39144386228221, 55.0223467555791], [-7.14703863785253, 55.0467238746553]]]}}, 
{"id": "N09000006", "type": "Feature", "properties": {"areaCode": "N09000006", "areaName": "Fermanagh and Omagh", "lat": 54.385208, "long": -7.5271, "newCasesByPublishDate": 0, "pop_total": 117397.0}, "geometry": {"type": "Polygon", "coordinates": [[[-6.94000526652459, 54.7735862770319], [-7.0111483263911, 54.7179164458596], [-6.97451346801048, 54.5436738653106], [-7.36702055464399, 54.4375109968609], [-7.14224373046422, 54.2556213291848], [-7.27950622073253, 54.1223799982782], [-7.86024218460512, 54.2175535507195], [-7.86188555448805, 54.2934868663368], [-8.17748428228008, 54.4647764398753], [-7.44786902453267, 54.6409673671176], [-7.30571657531746, 54.7384979023887], [-6.94000526652459, 54.7735862770319]]]}}, 
{"id": "N09000007", "type": "Feature", "properties": {"areaCode": "N09000007", "areaName": "Lisburn and Castlereagh", "lat": 54.49752, "long": -6.03545, "newCasesByPublishDate": 0, "pop_total": 146002.0}, "geometry": {"type": "Polygon", "coordinates": [[[-6.04553272895948, 54.6058944496858], [-5.97574465599047, 54.5305881456644], [-5.75746880588443, 54.5814493468674], [-6.01854109355525, 54.3704780281283], [-6.21018440507748, 54.4327414539901], [-6.30463487433425, 54.5728762162142], [-6.04553272895948, 54.6058944496858]]]}}, 
{"id": "N09000009", "type": "Feature", "properties": {"areaCode": "N09000009", "areaName": "Mid Ulster", "lat": 54.552731, "long": -6.8889, "newCasesByPublishDate": 0, "pop_total": 148528.0}, "geometry": {"type": "Polygon", "coordinates": [[[-6.49989811582067, 54.918760235465], [-6.42599769869378, 54.5682228227428], [-6.83703223420254, 54.3355920356199], [-7.02907277361944, 54.4213258057242], [-7.15271951714404, 54.3352258818404], [-7.33442900956349, 54.3716834169155], [-7.36702055464399, 54.4375109968609], [-6.97451346801048, 54.5436738653106], [-7.0111483263911, 54.7179164458596], [-6.8866002529905, 54.8529973410418], [-6.49989811582067, 54.918760235465]]]}}, 
{"id": "N09000008", "type": "Feature", "properties": {"areaCode": "N09000008", "areaName": "Mid and East Antrim", "lat": 54.86462, "long": -6.14645, "newCasesByPublishDate": 0, "pop_total": 139274.0}, "geometry": {"type": "Polygon", "coordinates": [[[-5.86825366596761, 54.6888687315215], [-5.88743175006564, 54.7723941141063], [-6.0098435957095, 54.8000951269846], [-6.47705679588031, 54.7809040831338], [-6.50629295628445, 54.9082576713827], [-5.97692873094826, 55.0562971809219], [-5.99007301125635, 54.984514642232], [-5.68964873973087, 54.8037059110952], [-5.86825366596761, 54.6888687315215]]]}}, 
{"id": "N09000010", "type": "Feature", "properties": {"areaCode": "N09000010", "areaName": "Newry, Mourne and Down", "lat": 54.149529, "long": -6.08891, "newCasesByPublishDate": 0, "pop_total": 181368.0}, "geometry": {"type": "Polygon", "coordinates": [[[-5.51597184422536, 54.3243388640101], [-5.66018062367681, 54.2256146968], [-5.81438348807952, 54.2864800457757], [-5.89692617268467, 54.1047041619978], [-6.06272153791029, 54.0227361083666], [-6.29088218758648, 54.1126750153287], [-6.6689790287571, 54.0728072786138], [-6.59991188551696, 54.2189466982227], [-6.43909451680779, 54.2674826587056], [-6.05037829121797, 54.2439277962008], [-6.09841841649155, 54.3265633644304], [-5.82346793804335, 54.495410544066], [-5.58374699641201, 54.4495151959215], [-5.51597184422536, 54.3243388640101]]]}}]}"""

gdf = gpd.GeoDataFrame.from_features(json.loads(geojs))
# divide into regions that can be used in dissolve
gdf["region"] = np.select(
    [gdf["lat"].gt(55), gdf["lat"].lt(54.2), gdf["long"].lt(-7), gdf["long"].gt(-6)],
    ["N", "S", "W", "E"],
    "C",
)
# what's does it originally look like
gdf.plot(column="pop_total")
# create column that sub-divides a region when population total goes over 300K boundaries
gdf = gdf.assign(
    subregion=gdf["region"] + gdf.groupby("region")["pop_total"]
    .transform(lambda s: s.cumsum() // (3 * 10 ** 5))
    .astype(str)
)
# dissovle to subregions
gdf.dissolve(by="subregion", aggfunc="sum").plot(column="pop_total")

在此处输入图像描述


推荐阅读