将数据导入 geopandas GeoDataFrame 的优雅方式
Elegant way to import data to a geopandas GeoDataFrame
我有一个基于 ISO3 国家代码的数据源,我希望使用 geopandas 将其可视化。我使用的来源是基于世界银行的数据,包含的国家比 GeoDataFrame 中的目标更多。
我使用下面的代码实现了我正在寻找的可视化效果。一些代码行更正了 world
层中缺失的缩写(有关详细信息,请参阅 https://github.com/geopandas/geopandas/issues/1041)。
现在我有两个问题。
- (major) 代码不是很优雅。有人知道更优雅的方法是将数据导入
world
GeoDataFrame 吗?
- (次要)我收到一个我不明白的 matplotlib 警告:
RuntimeWarning: invalid value encountered in less xa[xa < 0] = -1
重现问题的基本代码如下。抱歉,数组很长,但数据是重现问题所必需的。
import numpy as np
import matplotlib.pyplot as plt
import geopandas as gpd
# resulting data after a lot of operations
c = np.array([1, 6, 6, 1, 6, 6, 6, 5, 5, 5, 7, 5, 5, 7, 5, 6, 5, 6, 7, 5, 7, 7,
6, 7, 6, 4, 6, 1, 1, 7, 7, 5, 1, 1, 5, 6, 6, 6, 7, 1, 7, 6, 1, 5,
6, 5, 5, 5, 7, 6, 6, 6, 7, 6, 2, 7, 5, 1, 6, 5, 5, 5, 7, 1, 6, 5,
7, 5, 5, 6, 5, 7, 1, 1, 7, 7, 6, 5, 5, 5, 7, 7, 6, 7, 5, 5, 5, 6,
5, 6, 6, 7, 7, 5, 5, 7, 7, 6, 6, 7, 1, 6, 5, 6, 5, 5, 6, 7, 1, 6,
7, 1, 5, 6, 7, 6, 6, 7, 6, 7, 6, 7, 1, 7, 7, 7, 5, 5, 5, 6, 1, 1,
5, 5, 3, 6, 6, 7, 6, 6, 6, 5, 5, 5, 5, 6, 6, 1, 6, 5, 7, 5, 7, 6,
8, 1, 5, 5, 5, 7, 1, 6, 5, 6, 6, 6, 6, 7, 6, 7, 5, 5, 6, 7, 1, 6,
1, 7, 6, 5, 6, 7, 7, 7, 1, 6, 4, 5, 5, 6, 7, 6, 6, 6, 5, 7, 7, 1,
7], dtype=int)
iso3c = np.array(['AFG', 'ALB', 'DZA', 'AGO', 'ATG', 'ARG', 'ARM', 'ABW', 'AUS',
'AUT', 'AZE', 'BHS', 'BHR', 'BGD', 'BRB', 'BLR', 'BEL', 'BLZ',
'BEN', 'BMU', 'BTN', 'BOL', 'BIH', 'BWA', 'BRA', 'BRN', 'BGR',
'BFA', 'BDI', 'KHM', 'CMR', 'CAN', 'CAF', 'TCD', 'CHI', 'CHL',
'CHN', 'COL', 'COM', 'COD', 'COG', 'CRI', 'CIV', 'HRV', 'CUB',
'CYP', 'CZE', 'DNK', 'DJI', 'DMA', 'DOM', 'ECU', 'EGY', 'SLV',
'GNQ', 'ERI', 'EST', 'ETH', 'FJI', 'FIN', 'FRA', 'PYF', 'GAB',
'GMB', 'GEO', 'DEU', 'GHA', 'GRC', 'GRL', 'GRD', 'GUM', 'GTM',
'GIN', 'GNB', 'GUY', 'HTI', 'HND', 'HKG', 'HUN', 'ISL', 'IND',
'IDN', 'IRN', 'IRQ', 'IRL', 'ISR', 'ITA', 'JAM', 'JPN', 'JOR',
'KAZ', 'KEN', 'KIR', 'KOR', 'KWT', 'KGZ', 'LAO', 'LVA', 'LBN',
'LSO', 'LBR', 'LBY', 'LIE', 'LTU', 'LUX', 'MAC', 'MKD', 'MDG',
'MWI', 'MYS', 'MDV', 'MLI', 'MLT', 'MHL', 'MRT', 'MUS', 'MEX',
'FSM', 'MDA', 'MNG', 'MNE', 'MAR', 'MOZ', 'MMR', 'NAM', 'NPL',
'NLD', 'NCL', 'NZL', 'NIC', 'NER', 'NGA', 'NOR', 'OMN', 'PAK',
'PLW', 'PAN', 'PNG', 'PRY', 'PER', 'PHL', 'POL', 'PRT', 'PRI',
'QAT', 'ROU', 'RUS', 'RWA', 'WSM', 'SMR', 'STP', 'SAU', 'SEN',
'SRB', 'SYC', 'SLE', 'SGP', 'SVK', 'SVN', 'SLB', 'SOM', 'ZAF',
'ESP', 'LKA', 'KNA', 'LCA', 'VCT', 'SDN', 'SUR', 'SWZ', 'SWE',
'CHE', 'SYR', 'TJK', 'TZA', 'THA', 'TLS', 'TGO', 'TON', 'TTO',
'TUN', 'TUR', 'TKM', 'TUV', 'UGA', 'UKR', 'ARE', 'GBR', 'USA',
'URY', 'UZB', 'VUT', 'VEN', 'VNM', 'VIR', 'PSE', 'YEM', 'ZMB',
'ZWE'], dtype=object)
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
# just done because of an existing bug
world.loc[world['name'] == 'France', 'iso_a3'] = 'FRA'
world.loc[world['name'] == 'Norway', 'iso_a3'] = 'NOR'
world.loc[world['name'] == 'Somaliland', 'iso_a3'] = 'SOM'
world.loc[world['name'] == 'Kosovo', 'iso_a3'] = 'RKS'
world = world[(world.pop_est>0) & (world.name!="Antarctica")]
plotData = np.nan * np.ones(world.iso_a3.shape[0])
for i, country in enumerate(iso3c) :
for j, wcountry in enumerate(world.iso_a3) :
if country == wcountry:
plotData[j] = float(c[i])
world.plot(plotData, cmap='Paired')
我认为将数组放入数据框然后将其与 world
地理数据框合并会对您有所帮助。所以你会变成:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import geopandas as gpd
def fix_missing_codes(world):
# just done because of an existing bug
world2 = world.copy()
world2.loc[world['name'] == 'France', 'iso_a3'] = 'FRA'
world2.loc[world['name'] == 'Norway', 'iso_a3'] = 'NOR'
world2.loc[world['name'] == 'Somaliland', 'iso_a3'] = 'SOM'
world2.loc[world['name'] == 'Kosovo', 'iso_a3'] = 'RKS'
return world2
c = np.array([...])
iso3c = np.array([...])
colors = pd.DataFrame({
'color': c,
'iso_a3': iso3c
})
ax = (
gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
.loc[lambda df: (df['pop_est'] > 0) & (df['name'] != 'Antarctica')]
.pipe(fix_missing_codes)
.merge(colors, on='iso_a3')
.plot(column='color', cmap='Paired')
)
这也会消除你的警告。
我有一个基于 ISO3 国家代码的数据源,我希望使用 geopandas 将其可视化。我使用的来源是基于世界银行的数据,包含的国家比 GeoDataFrame 中的目标更多。
我使用下面的代码实现了我正在寻找的可视化效果。一些代码行更正了 world
层中缺失的缩写(有关详细信息,请参阅 https://github.com/geopandas/geopandas/issues/1041)。
现在我有两个问题。
- (major) 代码不是很优雅。有人知道更优雅的方法是将数据导入
world
GeoDataFrame 吗? - (次要)我收到一个我不明白的 matplotlib 警告:
RuntimeWarning: invalid value encountered in less xa[xa < 0] = -1
重现问题的基本代码如下。抱歉,数组很长,但数据是重现问题所必需的。
import numpy as np
import matplotlib.pyplot as plt
import geopandas as gpd
# resulting data after a lot of operations
c = np.array([1, 6, 6, 1, 6, 6, 6, 5, 5, 5, 7, 5, 5, 7, 5, 6, 5, 6, 7, 5, 7, 7,
6, 7, 6, 4, 6, 1, 1, 7, 7, 5, 1, 1, 5, 6, 6, 6, 7, 1, 7, 6, 1, 5,
6, 5, 5, 5, 7, 6, 6, 6, 7, 6, 2, 7, 5, 1, 6, 5, 5, 5, 7, 1, 6, 5,
7, 5, 5, 6, 5, 7, 1, 1, 7, 7, 6, 5, 5, 5, 7, 7, 6, 7, 5, 5, 5, 6,
5, 6, 6, 7, 7, 5, 5, 7, 7, 6, 6, 7, 1, 6, 5, 6, 5, 5, 6, 7, 1, 6,
7, 1, 5, 6, 7, 6, 6, 7, 6, 7, 6, 7, 1, 7, 7, 7, 5, 5, 5, 6, 1, 1,
5, 5, 3, 6, 6, 7, 6, 6, 6, 5, 5, 5, 5, 6, 6, 1, 6, 5, 7, 5, 7, 6,
8, 1, 5, 5, 5, 7, 1, 6, 5, 6, 6, 6, 6, 7, 6, 7, 5, 5, 6, 7, 1, 6,
1, 7, 6, 5, 6, 7, 7, 7, 1, 6, 4, 5, 5, 6, 7, 6, 6, 6, 5, 7, 7, 1,
7], dtype=int)
iso3c = np.array(['AFG', 'ALB', 'DZA', 'AGO', 'ATG', 'ARG', 'ARM', 'ABW', 'AUS',
'AUT', 'AZE', 'BHS', 'BHR', 'BGD', 'BRB', 'BLR', 'BEL', 'BLZ',
'BEN', 'BMU', 'BTN', 'BOL', 'BIH', 'BWA', 'BRA', 'BRN', 'BGR',
'BFA', 'BDI', 'KHM', 'CMR', 'CAN', 'CAF', 'TCD', 'CHI', 'CHL',
'CHN', 'COL', 'COM', 'COD', 'COG', 'CRI', 'CIV', 'HRV', 'CUB',
'CYP', 'CZE', 'DNK', 'DJI', 'DMA', 'DOM', 'ECU', 'EGY', 'SLV',
'GNQ', 'ERI', 'EST', 'ETH', 'FJI', 'FIN', 'FRA', 'PYF', 'GAB',
'GMB', 'GEO', 'DEU', 'GHA', 'GRC', 'GRL', 'GRD', 'GUM', 'GTM',
'GIN', 'GNB', 'GUY', 'HTI', 'HND', 'HKG', 'HUN', 'ISL', 'IND',
'IDN', 'IRN', 'IRQ', 'IRL', 'ISR', 'ITA', 'JAM', 'JPN', 'JOR',
'KAZ', 'KEN', 'KIR', 'KOR', 'KWT', 'KGZ', 'LAO', 'LVA', 'LBN',
'LSO', 'LBR', 'LBY', 'LIE', 'LTU', 'LUX', 'MAC', 'MKD', 'MDG',
'MWI', 'MYS', 'MDV', 'MLI', 'MLT', 'MHL', 'MRT', 'MUS', 'MEX',
'FSM', 'MDA', 'MNG', 'MNE', 'MAR', 'MOZ', 'MMR', 'NAM', 'NPL',
'NLD', 'NCL', 'NZL', 'NIC', 'NER', 'NGA', 'NOR', 'OMN', 'PAK',
'PLW', 'PAN', 'PNG', 'PRY', 'PER', 'PHL', 'POL', 'PRT', 'PRI',
'QAT', 'ROU', 'RUS', 'RWA', 'WSM', 'SMR', 'STP', 'SAU', 'SEN',
'SRB', 'SYC', 'SLE', 'SGP', 'SVK', 'SVN', 'SLB', 'SOM', 'ZAF',
'ESP', 'LKA', 'KNA', 'LCA', 'VCT', 'SDN', 'SUR', 'SWZ', 'SWE',
'CHE', 'SYR', 'TJK', 'TZA', 'THA', 'TLS', 'TGO', 'TON', 'TTO',
'TUN', 'TUR', 'TKM', 'TUV', 'UGA', 'UKR', 'ARE', 'GBR', 'USA',
'URY', 'UZB', 'VUT', 'VEN', 'VNM', 'VIR', 'PSE', 'YEM', 'ZMB',
'ZWE'], dtype=object)
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
# just done because of an existing bug
world.loc[world['name'] == 'France', 'iso_a3'] = 'FRA'
world.loc[world['name'] == 'Norway', 'iso_a3'] = 'NOR'
world.loc[world['name'] == 'Somaliland', 'iso_a3'] = 'SOM'
world.loc[world['name'] == 'Kosovo', 'iso_a3'] = 'RKS'
world = world[(world.pop_est>0) & (world.name!="Antarctica")]
plotData = np.nan * np.ones(world.iso_a3.shape[0])
for i, country in enumerate(iso3c) :
for j, wcountry in enumerate(world.iso_a3) :
if country == wcountry:
plotData[j] = float(c[i])
world.plot(plotData, cmap='Paired')
我认为将数组放入数据框然后将其与 world
地理数据框合并会对您有所帮助。所以你会变成:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import geopandas as gpd
def fix_missing_codes(world):
# just done because of an existing bug
world2 = world.copy()
world2.loc[world['name'] == 'France', 'iso_a3'] = 'FRA'
world2.loc[world['name'] == 'Norway', 'iso_a3'] = 'NOR'
world2.loc[world['name'] == 'Somaliland', 'iso_a3'] = 'SOM'
world2.loc[world['name'] == 'Kosovo', 'iso_a3'] = 'RKS'
return world2
c = np.array([...])
iso3c = np.array([...])
colors = pd.DataFrame({
'color': c,
'iso_a3': iso3c
})
ax = (
gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
.loc[lambda df: (df['pop_est'] > 0) & (df['name'] != 'Antarctica')]
.pipe(fix_missing_codes)
.merge(colors, on='iso_a3')
.plot(column='color', cmap='Paired')
)
这也会消除你的警告。