Compatibility with geopandas version 1 (#1136)

* address geopandas and pandas deprecations/warnings

* compatibility with geopandas v1

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Fabian Neumann 2024-07-08 08:29:16 +02:00 committed by GitHub
parent 43c0c3871f
commit c3151902f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 52 additions and 41 deletions

View File

@ -28,7 +28,7 @@ dependencies:
- powerplantmatching>=0.5.15 - powerplantmatching>=0.5.15
- numpy - numpy
- pandas>=2.1 - pandas>=2.1
- geopandas>=0.11.0, <1 - geopandas>=1
- xarray>=2023.11.0 - xarray>=2023.11.0
- rioxarray - rioxarray
- netcdf4 - netcdf4

View File

@ -287,9 +287,9 @@ def shapes_to_shapes(orig, dest):
transfer = sparse.lil_matrix((len(dest), len(orig)), dtype=float) transfer = sparse.lil_matrix((len(dest), len(orig)), dtype=float)
for i, j in product(range(len(dest)), range(len(orig))): for i, j in product(range(len(dest)), range(len(orig))):
if orig_prepped[j].intersects(dest[i]): if orig_prepped[j].intersects(dest.iloc[i]):
area = orig[j].intersection(dest[i]).area area = orig.iloc[j].intersection(dest.iloc[i]).area
transfer[i, j] = area / dest[i].area transfer[i, j] = area / dest.iloc[i].area
return transfer return transfer

View File

@ -671,7 +671,7 @@ def _set_links_underwater_fraction(n, offshore_shapes):
if not hasattr(n.links, "geometry"): if not hasattr(n.links, "geometry"):
n.links["underwater_fraction"] = 0.0 n.links["underwater_fraction"] = 0.0
else: else:
offshore_shape = gpd.read_file(offshore_shapes).unary_union offshore_shape = gpd.read_file(offshore_shapes).union_all()
links = gpd.GeoSeries(n.links.geometry.dropna().map(shapely.wkt.loads)) links = gpd.GeoSeries(n.links.geometry.dropna().map(shapely.wkt.loads))
n.links["underwater_fraction"] = ( n.links["underwater_fraction"] = (
links.intersection(offshore_shape).length / links.length links.intersection(offshore_shape).length / links.length
@ -874,7 +874,8 @@ def build_bus_shapes(n, country_shapes, offshore_shapes, countries):
onshore_locs.values, onshore_shape onshore_locs.values, onshore_shape
), ),
"country": country, "country": country,
} },
crs=n.crs,
) )
) )
@ -889,12 +890,14 @@ def build_bus_shapes(n, country_shapes, offshore_shapes, countries):
"y": offshore_locs["y"], "y": offshore_locs["y"],
"geometry": voronoi_partition_pts(offshore_locs.values, offshore_shape), "geometry": voronoi_partition_pts(offshore_locs.values, offshore_shape),
"country": country, "country": country,
} },
crs=n.crs,
) )
offshore_regions_c = offshore_regions_c.loc[offshore_regions_c.area > 1e-2] sel = offshore_regions_c.to_crs(3035).area > 10 # m2
offshore_regions_c = offshore_regions_c.loc[sel]
offshore_regions.append(offshore_regions_c) offshore_regions.append(offshore_regions_c)
shapes = pd.concat(onshore_regions, ignore_index=True) shapes = pd.concat(onshore_regions, ignore_index=True).set_crs(n.crs)
return onshore_regions, offshore_regions, shapes, offshore_shapes return onshore_regions, offshore_regions, shapes, offshore_shapes

View File

@ -7,6 +7,7 @@ Build import locations for fossil gas from entry-points, LNG terminals and
production sites with data from SciGRID_gas and Global Energy Monitor. production sites with data from SciGRID_gas and Global Energy Monitor.
""" """
import json
import logging import logging
import geopandas as gpd import geopandas as gpd
@ -19,7 +20,8 @@ logger = logging.getLogger(__name__)
def read_scigrid_gas(fn): def read_scigrid_gas(fn):
df = gpd.read_file(fn) df = gpd.read_file(fn)
df = pd.concat([df, df.param.apply(pd.Series)], axis=1) expanded_param = df.param.apply(json.loads).apply(pd.Series)
df = pd.concat([df, expanded_param], axis=1)
df.drop(["param", "uncertainty", "method"], axis=1, inplace=True) df.drop(["param", "uncertainty", "method"], axis=1, inplace=True)
return df return df
@ -97,11 +99,11 @@ def build_gas_input_locations(gem_fn, entry_fn, sto_fn, countries):
~(entry.from_country.isin(countries) & entry.to_country.isin(countries)) ~(entry.from_country.isin(countries) & entry.to_country.isin(countries))
& ~entry.name.str.contains("Tegelen") # only take non-EU entries & ~entry.name.str.contains("Tegelen") # only take non-EU entries
| (entry.from_country == "NO") # malformed datapoint # entries from NO to GB | (entry.from_country == "NO") # malformed datapoint # entries from NO to GB
] ].copy()
sto = read_scigrid_gas(sto_fn) sto = read_scigrid_gas(sto_fn)
remove_country = ["RU", "UA", "TR", "BY"] # noqa: F841 remove_country = ["RU", "UA", "TR", "BY"] # noqa: F841
sto = sto.query("country_code not in @remove_country") sto = sto.query("country_code not in @remove_country").copy()
# production sites inside the model scope # production sites inside the model scope
prod = build_gem_prod_data(gem_fn) prod = build_gem_prod_data(gem_fn)
@ -132,7 +134,8 @@ if __name__ == "__main__":
snakemake = mock_snakemake( snakemake = mock_snakemake(
"build_gas_input_locations", "build_gas_input_locations",
simpl="", simpl="",
clusters="128", clusters="5",
configfiles="config/test/config.overnight.yaml",
) )
configure_logging(snakemake) configure_logging(snakemake)
@ -162,7 +165,7 @@ if __name__ == "__main__":
gas_input_nodes = gpd.sjoin(gas_input_locations, regions, how="left") gas_input_nodes = gpd.sjoin(gas_input_locations, regions, how="left")
gas_input_nodes.rename(columns={"index_right": "bus"}, inplace=True) gas_input_nodes.rename(columns={"name": "bus"}, inplace=True)
gas_input_nodes.to_file(snakemake.output.gas_input_nodes, driver="GeoJSON") gas_input_nodes.to_file(snakemake.output.gas_input_nodes, driver="GeoJSON")

View File

@ -7,6 +7,7 @@ Preprocess gas network based on data from bthe SciGRID_gas project
(https://www.gas.scigrid.de/). (https://www.gas.scigrid.de/).
""" """
import json
import logging import logging
import geopandas as gpd import geopandas as gpd
@ -54,8 +55,9 @@ def diameter_to_capacity(pipe_diameter_mm):
def load_dataset(fn): def load_dataset(fn):
df = gpd.read_file(fn) df = gpd.read_file(fn)
param = df.param.apply(pd.Series) param = df.param.apply(json.loads).apply(pd.Series)
method = df.method.apply(pd.Series)[["diameter_mm", "max_cap_M_m3_per_d"]] cols = ["diameter_mm", "max_cap_M_m3_per_d"]
method = df.method.apply(json.loads).apply(pd.Series)[cols]
method.columns = method.columns + "_method" method.columns = method.columns + "_method"
df = pd.concat([df, param, method], axis=1) df = pd.concat([df, param, method], axis=1)
to_drop = ["param", "uncertainty", "method", "tags"] to_drop = ["param", "uncertainty", "method", "tags"]

View File

@ -41,10 +41,10 @@ if __name__ == "__main__":
from _helpers import mock_snakemake from _helpers import mock_snakemake
snakemake = mock_snakemake( snakemake = mock_snakemake(
"build_hourly_heat_demands", "build_hourly_heat_demand",
scope="total", scope="total",
simpl="", simpl="",
clusters=48, clusters=5,
) )
set_scenario_config(snakemake) set_scenario_config(snakemake)
@ -85,6 +85,6 @@ if __name__ == "__main__":
heat_demand.index.name = "snapshots" heat_demand.index.name = "snapshots"
ds = heat_demand.stack().to_xarray() ds = heat_demand.stack(future_stack=True).to_xarray()
ds.to_netcdf(snakemake.output.heat_demand) ds.to_netcdf(snakemake.output.heat_demand)

View File

@ -116,7 +116,7 @@ def prepare_hotmaps_database(regions):
gdf = gpd.sjoin(gdf, regions, how="inner", predicate="within") gdf = gpd.sjoin(gdf, regions, how="inner", predicate="within")
gdf.rename(columns={"index_right": "bus"}, inplace=True) gdf.rename(columns={"name": "bus"}, inplace=True)
gdf["country"] = gdf.bus.str[:2] gdf["country"] = gdf.bus.str[:2]
# the .sjoin can lead to duplicates if a geom is in two overlapping regions # the .sjoin can lead to duplicates if a geom is in two overlapping regions

View File

@ -184,7 +184,7 @@ def separate_basic_chemicals(demand, production):
demand.drop(columns="Basic chemicals", inplace=True) demand.drop(columns="Basic chemicals", inplace=True)
demand["HVC"].clip(lower=0, inplace=True) demand["HVC"] = demand["HVC"].clip(lower=0)
return demand return demand
@ -248,7 +248,7 @@ if __name__ == "__main__":
demand = add_non_eu28_industrial_energy_demand(countries, demand, production) demand = add_non_eu28_industrial_energy_demand(countries, demand, production)
# for format compatibility # for format compatibility
demand = demand.stack(dropna=False).unstack(level=[0, 2]) demand = demand.stack(future_stack=True).unstack(level=[0, 2])
# style and annotation # style and annotation
demand.index.name = "TWh/a" demand.index.name = "TWh/a"

View File

@ -301,7 +301,8 @@ def separate_basic_chemicals(demand, year):
demand["Basic chemicals"] -= demand["Ammonia"] demand["Basic chemicals"] -= demand["Ammonia"]
# EE, HR and LT got negative demand through subtraction - poor data # EE, HR and LT got negative demand through subtraction - poor data
demand["Basic chemicals"].clip(lower=0.0, inplace=True) col = "Basic chemicals"
demand[col] = demand[col].clip(lower=0.0)
# assume HVC, methanol, chlorine production proportional to non-ammonia basic chemicals # assume HVC, methanol, chlorine production proportional to non-ammonia basic chemicals
distribution_key = ( distribution_key = (

View File

@ -92,7 +92,9 @@ if __name__ == "__main__":
# The first low density grid cells to reach rural fraction are rural # The first low density grid cells to reach rural fraction are rural
asc_density_i = density_cells_ct.sort_values().index asc_density_i = density_cells_ct.sort_values().index
asc_density_cumsum = pop_cells_ct[asc_density_i].cumsum() / pop_cells_ct.sum() asc_density_cumsum = (
pop_cells_ct.iloc[asc_density_i].cumsum() / pop_cells_ct.sum()
)
rural_fraction_ct = 1 - urban_fraction[ct] rural_fraction_ct = 1 - urban_fraction[ct]
pop_ct_rural_b = asc_density_cumsum < rural_fraction_ct pop_ct_rural_b = asc_density_cumsum < rural_fraction_ct
pop_ct_urban_b = ~pop_ct_rural_b pop_ct_urban_b = ~pop_ct_rural_b

View File

@ -406,7 +406,7 @@ if __name__ == "__main__":
if snakemake.wildcards.technology.startswith("offwind"): if snakemake.wildcards.technology.startswith("offwind"):
logger.info("Calculate underwater fraction of connections.") logger.info("Calculate underwater fraction of connections.")
offshore_shape = gpd.read_file(snakemake.input["offshore_shapes"]).unary_union offshore_shape = gpd.read_file(snakemake.input["offshore_shapes"]).union_all()
underwater_fraction = [] underwater_fraction = []
for bus in buses: for bus in buses:
p = centre_of_mass.sel(bus=bus).data p = centre_of_mass.sel(bus=bus).data

View File

@ -124,7 +124,7 @@ def countries(naturalearth, country_list):
df = df.loc[ df = df.loc[
df.name.isin(country_list) & ((df["scalerank"] == 0) | (df["scalerank"] == 5)) df.name.isin(country_list) & ((df["scalerank"] == 0) | (df["scalerank"] == 5))
] ]
s = df.set_index("name")["geometry"].map(_simplify_polys) s = df.set_index("name")["geometry"].map(_simplify_polys).set_crs(df.crs)
if "RS" in country_list: if "RS" in country_list:
s["RS"] = s["RS"].union(s.pop("KV")) s["RS"] = s["RS"].union(s.pop("KV"))
# cleanup shape union # cleanup shape union
@ -145,7 +145,8 @@ def eez(country_shapes, eez, country_list):
lambda s: _simplify_polys(s, filterremote=False) lambda s: _simplify_polys(s, filterremote=False)
) )
s = gpd.GeoSeries( s = gpd.GeoSeries(
{k: v for k, v in s.items() if v.distance(country_shapes[k]) < 1e-3} {k: v for k, v in s.items() if v.distance(country_shapes[k]) < 1e-3},
crs=df.crs,
) )
s = s.to_frame("geometry") s = s.to_frame("geometry")
s.index.name = "name" s.index.name = "name"
@ -156,7 +157,7 @@ def country_cover(country_shapes, eez_shapes=None):
shapes = country_shapes shapes = country_shapes
if eez_shapes is not None: if eez_shapes is not None:
shapes = pd.concat([shapes, eez_shapes]) shapes = pd.concat([shapes, eez_shapes])
europe_shape = shapes.unary_union europe_shape = shapes.union_all()
if isinstance(europe_shape, MultiPolygon): if isinstance(europe_shape, MultiPolygon):
europe_shape = max(europe_shape.geoms, key=attrgetter("area")) europe_shape = max(europe_shape.geoms, key=attrgetter("area"))
return Polygon(shell=europe_shape.exterior) return Polygon(shell=europe_shape.exterior)
@ -235,11 +236,11 @@ def nuts3(country_shapes, nuts3, nuts3pop, nuts3gdp, ch_cantons, ch_popgdp):
[["BA1", "BA", 3871.0], ["RS1", "RS", 7210.0], ["AL1", "AL", 2893.0]], [["BA1", "BA", 3871.0], ["RS1", "RS", 7210.0], ["AL1", "AL", 2893.0]],
columns=["NUTS_ID", "country", "pop"], columns=["NUTS_ID", "country", "pop"],
geometry=gpd.GeoSeries(), geometry=gpd.GeoSeries(),
crs=df.crs,
) )
manual["geometry"] = manual["country"].map(country_shapes) manual["geometry"] = manual["country"].map(country_shapes.to_crs(df.crs))
manual = manual.dropna() manual = manual.dropna()
manual = manual.set_index("NUTS_ID") manual = manual.set_index("NUTS_ID")
manual = manual.set_crs("ETRS89")
df = pd.concat([df, manual], sort=False) df = pd.concat([df, manual], sort=False)
@ -265,7 +266,8 @@ if __name__ == "__main__":
offshore_shapes.reset_index().to_file(snakemake.output.offshore_shapes) offshore_shapes.reset_index().to_file(snakemake.output.offshore_shapes)
europe_shape = gpd.GeoDataFrame( europe_shape = gpd.GeoDataFrame(
geometry=[country_cover(country_shapes, offshore_shapes.geometry)] geometry=[country_cover(country_shapes, offshore_shapes.geometry)],
crs=country_shapes.crs,
) )
europe_shape.reset_index().to_file(snakemake.output.europe_shape) europe_shape.reset_index().to_file(snakemake.output.europe_shape)

View File

@ -45,9 +45,7 @@ if __name__ == "__main__":
# assign ports to nearest region # assign ports to nearest region
p = european_ports.to_crs(3857) p = european_ports.to_crs(3857)
r = regions.to_crs(3857) r = regions.to_crs(3857)
outflows = ( outflows = p.sjoin_nearest(r).groupby("name").properties_outflows.sum().div(1e3)
p.sjoin_nearest(r).groupby("index_right").properties_outflows.sum().div(1e3)
)
# calculate fraction of each country's port outflows # calculate fraction of each country's port outflows
countries = outflows.index.str[:2] countries = outflows.index.str[:2]

View File

@ -41,9 +41,9 @@ def build_clustered_gas_network(df, bus_regions, length_factor=1.25):
for i in [0, 1]: for i in [0, 1]:
gdf = gpd.GeoDataFrame(geometry=df[f"point{i}"], crs="EPSG:4326") gdf = gpd.GeoDataFrame(geometry=df[f"point{i}"], crs="EPSG:4326")
bus_mapping = gpd.sjoin( bus_mapping = gpd.sjoin(gdf, bus_regions, how="left", predicate="within")[
gdf, bus_regions, how="left", predicate="within" "name"
).index_right ]
bus_mapping = bus_mapping.groupby(bus_mapping.index).first() bus_mapping = bus_mapping.groupby(bus_mapping.index).first()
df[f"bus{i}"] = bus_mapping df[f"bus{i}"] = bus_mapping

View File

@ -147,7 +147,7 @@ if __name__ == "__main__":
regions_geometry = regions.to_crs(3035).geometry regions_geometry = regions.to_crs(3035).geometry
band, transform = shape_availability(regions_geometry, excluder) band, transform = shape_availability(regions_geometry, excluder)
fig, ax = plt.subplots(figsize=(4, 8)) fig, ax = plt.subplots(figsize=(4, 8))
gpd.GeoSeries(regions_geometry.unary_union).plot(ax=ax, color="none") gpd.GeoSeries(regions_geometry.union_all()).plot(ax=ax, color="none")
show(band, transform=transform, cmap="Greens", ax=ax) show(band, transform=transform, cmap="Greens", ax=ax)
plt.axis("off") plt.axis("off")
plt.savefig(snakemake.output.availability_map, bbox_inches="tight", dpi=500) plt.savefig(snakemake.output.availability_map, bbox_inches="tight", dpi=500)

View File

@ -3718,7 +3718,7 @@ def lossy_bidirectional_links(n, carrier, efficiencies={}):
rev_links.index = rev_links.index.map(lambda x: x + "-reversed") rev_links.index = rev_links.index.map(lambda x: x + "-reversed")
n.links = pd.concat([n.links, rev_links], sort=False) n.links = pd.concat([n.links, rev_links], sort=False)
n.links["reversed"] = n.links["reversed"].fillna(False) n.links["reversed"] = n.links["reversed"].fillna(False).infer_objects(copy=False)
n.links["length_original"] = n.links["length_original"].fillna(n.links.length) n.links["length_original"] = n.links["length_original"].fillna(n.links.length)
# do compression losses after concatenation to take electricity consumption at bus0 in either direction # do compression losses after concatenation to take electricity consumption at bus0 in either direction

View File

@ -155,7 +155,7 @@ def _add_land_use_constraint(n):
existing_large, "p_nom_min" existing_large, "p_nom_min"
] ]
n.generators.p_nom_max.clip(lower=0, inplace=True) n.generators["p_nom_max"] = n.generators["p_nom_max"].clip(lower=0)
def _add_land_use_constraint_m(n, planning_horizons, config): def _add_land_use_constraint_m(n, planning_horizons, config):
@ -207,7 +207,7 @@ def _add_land_use_constraint_m(n, planning_horizons, config):
existing_large, "p_nom_min" existing_large, "p_nom_min"
] ]
n.generators.p_nom_max.clip(lower=0, inplace=True) n.generators["p_nom_max"] = n.generators["p_nom_max"].clip(lower=0)
def add_solar_potential_constraints(n, config): def add_solar_potential_constraints(n, config):