mirror of
https://github.com/wassname/geopandas.git
synced 2026-09-09 11:22:50 +08:00
REGR: fix recursion error in GeoDataFrame constructor with MultiIndex (#2497)
* REGR: fix recursion error in GeoDataFrame constructor with MultiIndex * Add test for pivot (GH-2057) * add changelog Co-authored-by: Matt Richards <45483497+m-richards@users.noreply.github.com>
This commit is contained in:
co-authored by
Matt Richards
parent
a844ee90b9
commit
5c8ae832e0
@@ -15,6 +15,10 @@ Deprecations and compatibility notes:
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix regression (RecursionError) in reshape methods such as ``unstack()``
|
||||
and ``pivot()`` involving MultiIndex, or GeoDataFrame construction with
|
||||
MultiIndex (#2486).
|
||||
|
||||
Notes on (optional) dependencies:
|
||||
|
||||
Version 0.11 (June 20, 2022)
|
||||
|
||||
@@ -148,7 +148,11 @@ class GeoDataFrame(GeoPandasBase, DataFrame):
|
||||
if crs is not None and data.crs != crs:
|
||||
raise ValueError(crs_mismatch_error)
|
||||
|
||||
if geometry is None and "geometry" in self.columns:
|
||||
if (
|
||||
geometry is None
|
||||
and self.columns.nlevels == 1
|
||||
and "geometry" in self.columns
|
||||
):
|
||||
# Check for multiple columns with name "geometry". If there are,
|
||||
# self["geometry"] is a gdf and constructor gets recursively recalled
|
||||
# by pandas internals trying to access this
|
||||
|
||||
@@ -1220,6 +1220,25 @@ class TestConstructor:
|
||||
with pytest.raises(ValueError):
|
||||
GeoDataFrame(df3, geometry="geom")
|
||||
|
||||
@pytest.mark.parametrize("dtype", ["geometry", "object"])
|
||||
def test_multiindex_with_geometry_label(self, dtype):
|
||||
# DataFrame with MultiIndex where "geometry" label corresponds to
|
||||
# multiple columns
|
||||
df = pd.DataFrame([[Point(0, 0), Point(1, 1)], [Point(2, 2), Point(3, 3)]])
|
||||
df = df.astype(dtype)
|
||||
df.columns = pd.MultiIndex.from_product([["geometry"], [0, 1]])
|
||||
# don't error in constructor
|
||||
gdf = GeoDataFrame(df)
|
||||
# Getting the .geometry column gives GeoDataFrame for both columns
|
||||
# (but with first MultiIndex level removed)
|
||||
# TODO should this give an error instead?
|
||||
result = gdf.geometry
|
||||
assert result.shape == gdf.shape
|
||||
assert result.columns.tolist() == [0, 1]
|
||||
assert_frame_equal(result, gdf["geometry"])
|
||||
result = gdf[["geometry"]]
|
||||
assert_frame_equal(result, gdf if dtype == "geometry" else pd.DataFrame(gdf))
|
||||
|
||||
|
||||
def test_geodataframe_crs():
|
||||
gdf = GeoDataFrame(columns=["geometry"])
|
||||
|
||||
@@ -289,6 +289,11 @@ def test_expanddim_in_unstack():
|
||||
else: # pandas GH37369, unstack doesn't call finalize
|
||||
assert unstack._geometry_column_name == "geometry"
|
||||
|
||||
# https://github.com/geopandas/geopandas/issues/2486
|
||||
s.name = "geometry"
|
||||
unstack = s.unstack()
|
||||
assert_object(unstack, GeoDataFrame, None, None)
|
||||
|
||||
|
||||
# indexing / constructor_sliced tests
|
||||
|
||||
|
||||
@@ -657,6 +657,16 @@ def test_df_apply_returning_series(df):
|
||||
assert_series_equal(result, df["value1"].rename(None))
|
||||
|
||||
|
||||
def test_pivot(df):
|
||||
# https://github.com/geopandas/geopandas/issues/2057
|
||||
# pivot failing due to creating a MultiIndex
|
||||
result = df.pivot(columns="value1")
|
||||
expected = GeoDataFrame(pd.DataFrame(df).pivot(columns="value1"))
|
||||
# TODO assert_geodataframe_equal crashes
|
||||
assert isinstance(result, GeoDataFrame)
|
||||
assert_frame_equal(result, expected)
|
||||
|
||||
|
||||
def test_preserve_attrs(df):
|
||||
# https://github.com/geopandas/geopandas/issues/1654
|
||||
df.attrs["name"] = "my_name"
|
||||
|
||||
Reference in New Issue
Block a user