import pandas as pd
import geopandas as gpd
import pyogrio
import topojson as tp

export.csv comes from https://www.volby.cz/pls/prez2023nss/pe71?xjazyk=CZ#/0-01-2023-0.

results = pd.read_csv("export.csv", sep=";", skiprows=[1, 2])

Download the 1.zip file from https://services.cuzk.cz/gml/inspire/au/epsg-5514/

admin_units = gpd.read_file("1.zip", layer="AdministrativeUnit")
obce = admin_units.query("LocalisedCharacterString == 'Obec'")
r_with_code = results.merge(obce[["nationalCode", "text"]], how="left", left_on="Obec / Kandidát (2023-2)", right_on="text")
extracted_code = r_with_code["Obec / Kandidát (2023-2)"].str.extract(r',\s*(\d+)\)$')
r_with_code.loc[extracted_code[0].notna(), "nationalCode"] = extracted_code[0][extracted_code[0].notna()]
r_with_code["nationalCode"] = r_with_code["nationalCode"].astype(obce.nationalCode.dtype)
obce
gml_id nationalCode localId namespace LocalisedCharacterString language sourceOfName pronunciation text script residenceOfAuthority beginLifespanVersion endLifespanVersion identifier identifierScheme geometry
92 AU.4.500852 500852 AU.4.500852 CZ_00025712-CUZK_AU Obec ces Český úřad zeměměřický a katastrální None Bohuňovice Latn None 2023-07-21T13:07:12Z None CZ0712500852 http://www.cuzk.cz/RUIAN/SHNCode MULTIPOLYGON (((-546147.820 -1116859.910, -546...
93 AU.4.500861 500861 AU.4.500861 CZ_00025712-CUZK_AU Obec ces Český úřad zeměměřický a katastrální None Bouzov Latn None 2021-10-27T03:07:12Z None CZ0712500861 http://www.cuzk.cz/RUIAN/SHNCode MULTIPOLYGON (((-575404.020 -1106019.400, -575...
94 AU.4.505081 505081 AU.4.505081 CZ_00025712-CUZK_AU Obec ces Český úřad zeměměřický a katastrální None Senice na Hané Latn None 2021-12-03T11:07:12Z None CZ0712505081 http://www.cuzk.cz/RUIAN/SHNCode MULTIPOLYGON (((-562638.830 -1116199.450, -562...
95 AU.4.500879 500879 AU.4.500879 CZ_00025712-CUZK_AU Obec ces Český úřad zeměměřický a katastrální None Bystročice Latn None 2023-06-01T17:07:12Z None CZ0712500879 http://www.cuzk.cz/RUIAN/SHNCode MULTIPOLYGON (((-553889.210 -1125733.180, -553...
96 AU.4.501476 501476 AU.4.501476 CZ_00025712-CUZK_AU Obec ces Český úřad zeměměřický a katastrální None Dlouhá Loučka Latn None 2021-11-25T21:07:12Z None CZ0712501476 http://www.cuzk.cz/RUIAN/SHNCode MULTIPOLYGON (((-546875.690 -1094194.530, -546...
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
6345 AU.4.579530 579530 AU.4.579530 CZ_00025712-CUZK_AU Obec ces Český úřad zeměměřický a katastrální None Maršov u Úpice Latn None 2022-04-29T17:07:12Z None CZ0525579530 http://www.cuzk.cz/RUIAN/SHNCode MULTIPOLYGON (((-628631.120 -1013025.530, -628...
6346 AU.4.540692 540692 AU.4.540692 CZ_00025712-CUZK_AU Obec ces Český úřad zeměměřický a katastrální None Sedliště Latn None 2023-04-12T15:07:12Z None CZ0324540692 http://www.cuzk.cz/RUIAN/SHNCode MULTIPOLYGON (((-809815.050 -1094938.250, -809...
6347 AU.4.573621 573621 AU.4.573621 CZ_00025712-CUZK_AU Obec ces Český úřad zeměměřický a katastrální None Hvozdnice Latn None 2023-05-30T11:07:12Z None CZ0521573621 http://www.cuzk.cz/RUIAN/SHNCode MULTIPOLYGON (((-649691.240 -1042358.600, -649...
6348 AU.4.551465 551465 AU.4.551465 CZ_00025712-CUZK_AU Obec ces Český úřad zeměměřický a katastrální None Košice Latn None 2023-04-03T11:07:12Z None CZ0205551465 http://www.cuzk.cz/RUIAN/SHNCode MULTIPOLYGON (((-694427.300 -1071598.720, -694...
6349 AU.4.530611 530611 AU.4.530611 CZ_00025712-CUZK_AU Obec ces Český úřad zeměměřický a katastrální None Smilkov Latn None 2023-05-23T13:07:12Z None CZ0201530611 http://www.cuzk.cz/RUIAN/SHNCode MULTIPOLYGON (((-734918.290 -1096640.520, -734...

6258 rows × 16 columns

data = r_with_code.drop(columns="text").merge(obce[["nationalCode", "sourceOfName", "geometry"]], on='nationalCode').set_geometry("geometry")
topo = tp.Topology(data, prequantize=False)
/Users/martin/mambaforge/envs/sds/lib/python3.11/site-packages/topojson/core/dedup.py:107: RuntimeWarning: invalid value encountered in cast
  data["bookkeeping_shared_arcs"] = array_bk_sarcs.astype(np.int64).tolist()
simplified = topo.toposimplify(500).to_gdf()
simplified.geometry = simplified.geometry.make_valid()
/Users/martin/mambaforge/envs/sds/lib/python3.11/site-packages/shapely/constructive.py:881: RuntimeWarning: invalid value encountered in simplify_preserve_topology
  return lib.simplify_preserve_topology(geometry, tolerance, **kwargs)
/Users/martin/mambaforge/envs/sds/lib/python3.11/site-packages/shapely/constructive.py:542: RuntimeWarning: invalid value encountered in make_valid
  return lib.make_valid(geometry, **kwargs)
simplified = simplified.rename(columns={"Obec / Kandidát (2023-2)": "name"})
simplified = simplified.explode(ignore_index=True).explode(ignore_index=True)
simplified = simplified[simplified.geom_type == "Polygon"]
simplified = simplified.dissolve("nationalCode", as_index=False)
simplified["PetrPavel"] = simplified["Petr Pavel"].str.replace(",", ".").astype(float)
simplified["AndrejBabis"] = simplified["Andrej Babiš"].str.replace(",", ".").astype(float)
simplified.drop(columns=["Petr Pavel", "Andrej Babiš"]).to_file("../../autocorrelation/data/cz_elections_2023.gpkg")
data = gpd.read_file("../../autocorrelation/data/cz_elections_2023.gpkg")