Skip to content

Commit 5cb9b8a

Browse files
author
Oliver Smith
committed
Updated pandas syntax for pandas3 compatability
1 parent 3ee1f22 commit 5cb9b8a

8 files changed

Lines changed: 146 additions & 112 deletions

File tree

-795 KB
Binary file not shown.
-69 Bytes
Binary file not shown.

environment.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
###############################################################################
22
# NOTE: This file has been auto-generated by poetry2conda
33
# poetry2conda version = 0.3.0
4-
# date: Tue Mar 24 13:04:56 2026
4+
# date: Tue Mar 24 15:49:13 2026
55
###############################################################################
66
# If you want to change the contents of this file, you should probably change
77
# the pyproject.toml file and then use poetry2conda again to update this file.
@@ -12,7 +12,7 @@ dependencies:
1212
- python>=3.11,<3.14
1313
- shapely>=2.0,<3.0
1414
- conda-forge::eppy-core>=0.5.63,<0.6.0
15-
- pandas>=2.2,<3.0
15+
- pandas>=2.2,<4.0
1616
- numpy>=1.26,<3.0
1717
- matplotlib>=3.8,<4.0
1818
- conda-forge::geopandas>=1.0,<2.0

poetry.lock

Lines changed: 77 additions & 98 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ packages = [{include = "simstock", from = "src"}]
1414
python = ">=3.11,<3.14"
1515
shapely = ">=2.0,<3.0"
1616
eppy = ">=0.5.63,<0.6.0"
17-
pandas = ">=2.2,<3.0"
17+
pandas = ">=2.2,<4.0"
1818
numpy = ">=1.26,<3.0"
1919
matplotlib = ">=3.8,<4.0"
2020
geopandas = ">=1.0,<2.0"

src/simstock/base.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,11 @@ def polygon_topology(self, **kwargs) -> None:
928928
# Create column named ``touching``. Each element
929929
# is an empty list
930930
length_range = range(self._df.__len__())
931-
self._df['touching'] = pd.Series([] for _ in length_range)
931+
self._df["touching"] = pd.Series(
932+
[[] for _ in length_range],
933+
index=self._df.index,
934+
dtype=object,
935+
)
932936

933937
# Iterate over all possible pairs of polygons in the data
934938
for i, j in itertools.combinations(length_range, 2):
@@ -943,8 +947,8 @@ def polygon_topology(self, **kwargs) -> None:
943947
# also add i's osbg to j's
944948
# ``touching`` column
945949
if algs._is_touching(poly_i, poly_j):
946-
self._df['touching'][i].append(osgb_j)
947-
self._df['touching'][j].append(osgb_i)
950+
self._df.at[i, "touching"].append(osgb_j)
951+
self._df.at[j, "touching"].append(osgb_i)
948952

949953
# If polygon i intersects polygon j, then the
950954
# _is_touching function will throw a ValueError.
@@ -993,15 +997,19 @@ def _polygon_within_hole(self) -> None:
993997
# Create column named ``poly_within_hole``. Each element
994998
# is an empty list
995999
length_range = range(self._df.__len__())
996-
self._df['poly_within_hole'] = pd.Series([] for _ in length_range)
1000+
self._df["poly_within_hole"] = pd.Series(
1001+
[[] for _ in length_range],
1002+
index=self._df.index,
1003+
dtype=object,
1004+
)
9971005

9981006
# Iterate over the cartesian product of polygons
9991007
for i, j in itertools.product(length_range, length_range):
10001008
if i != j and self._df['interiors'][i]:
10011009

10021010
# If polygon i has interiors, then check if polygon j
10031011
# touches polygon i
1004-
touches = self._df['osgb'][j] in self._df['touching'][i]
1012+
touches = self._df.at[j, "osgb"] in self._df.at[i, "touching"]
10051013

10061014
# Now iterate over the interiors of polygon i
10071015
for item in self._df['polygon'][i].interiors:
@@ -1010,10 +1018,8 @@ def _polygon_within_hole(self) -> None:
10101018
# If the interior both touchs and contains j, then we know
10111019
# j exists within a hole inside i
10121020
# We make a note of this in the `poly_within_hole` column
1013-
if item_poly.contains(self._df['polygon'][j]) and touches:
1014-
self._df['poly_within_hole'][i].append(
1015-
self._df['osgb'][j]
1016-
)
1021+
if item_poly.contains(self._df.at[j, "polygon"]) and touches:
1022+
self._df.at[i, "poly_within_hole"].append(self._df.at[j, "osgb"])
10171023

10181024
def _polygon_buffer(self) -> None:
10191025
for i, polygon in enumerate(self._df['polygon']):

src/simstock/plotting.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
LineString,
1717
MultiPolygon
1818
)
19-
from pandas.core.series import Series
20-
from pandas.core.frame import DataFrame
19+
from pandas import Series, DataFrame
2120
from simstock.base import SimstockDataframe
2221

2322

tests/test_simstockdataframe.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,56 @@ def test_simstockdf_invalid_df_geoms(self) -> None:
106106
"""
107107
with self.assertRaises(TypeError):
108108
SimstockDataframe(self.df_invalid_geoms)
109+
110+
def test_touching_lists_are_independent(self) -> None:
111+
"""
112+
Regression test to check that the lists in the ``touching`` column are independent
113+
of each other after upgrading to later pandas version syntax.
114+
"""
115+
df = pd.DataFrame({
116+
"id": ["a", "b"],
117+
"osgb": ["osgb_a", "osgb_b"],
118+
"polygon": [
119+
"POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))",
120+
"POLYGON ((3 0, 3 1, 4 1, 4 0, 3 0))",
121+
],
122+
"shading": [False, False],
123+
"height": [5.0, 5.0],
124+
"wwr": [0.2, 0.2],
125+
"nofloors": [2, 2],
126+
"construction": ["x", "x"],
127+
})
128+
sdf = SimstockDataframe(df)
129+
sdf.polygon_topology()
130+
131+
self.assertIsNot(sdf._df.at[0, "touching"], sdf._df.at[1, "touching"])
132+
sdf._df.at[0, "touching"].append("probe")
133+
self.assertEqual(sdf._df.at[0, "touching"], ["probe"])
134+
self.assertEqual(sdf._df.at[1, "touching"], [])
135+
136+
def test_osgb_string_dtype_in_topology(self) -> None:
137+
"""
138+
Regression test to check that the osgb column is still of string dtype
139+
after upgrading to later pandas version syntax in the polygon_topology method.
140+
"""
141+
df = pd.DataFrame({
142+
"id": ["a", "b"],
143+
"osgb": pd.Series(["osgb_a", "osgb_b"], dtype="string"),
144+
"polygon": [
145+
"POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))",
146+
"POLYGON ((1 0, 1 1, 2 1, 2 0, 1 0))",
147+
],
148+
"shading": [False, False],
149+
"height": [5.0, 5.0],
150+
"wwr": [0.2, 0.2],
151+
"nofloors": [2, 2],
152+
"construction": ["x", "x"],
153+
})
154+
sdf = SimstockDataframe(df)
155+
sdf.polygon_topology()
156+
157+
self.assertIn("osgb_b", sdf._df.at[0, "touching"])
158+
self.assertIn("osgb_a", sdf._df.at[1, "touching"])
109159

110160
def test_simstockdf_invalid_df_osgbnames(self) -> None:
111161
"""

0 commit comments

Comments
 (0)