Repository: geopandas/geopandas

Issue:
BUG: iloc indexing Dataframe with only one column (`geometry`) raises TypeError
- [x] I have checked that this issue has not already been reported.

- [x] I have confirmed this bug exists on the latest version of geopandas.

- [ ] (optional) I have confirmed this bug exists on the master branch of geopandas.

---

#### Code Sample, a copy-pastable example

```python
from shapely.geometry import Polygon
from geopandas import GeoSeries, GeoDataFrame

polys = GeoSeries(
    [
        Polygon([(0, 0), (2, 0), (2, 2), (0, 2)]),
        Polygon([(1, 1), (3, 1), (3, 3), (1, 3)]),
    ]
)

gdf = GeoDataFrame({"geometry": polys, "number": range(len(polys))})
gdf.iloc[[0]] = gdf.iloc[[1]]  # works

gdf = GeoDataFrame({"geometry": polys})
gdf.iloc[[0]] = gdf.iloc[[1]]  # does not work
```

#### Problem description

One may not always have other columns than `geometry` when wanting to use .iloc

Example of code where I first encountered this issue:
```python
from shapely.geometry import Polygon
from geopandas import GeoSeries, GeoDataFrame, overlay

polys = GeoSeries(
    [
        Polygon([(0, 0), (2, 0), (2, 2), (0, 2)]),
        Polygon([(1, 1), (3, 1), (3, 3), (1, 3)]),
        Polygon([(2, 2), (4, 2), (4, 4), (2, 4)]),
    ]
)

gdf = GeoDataFrame({"geometry": polys})

for i in range(0, len(gdf) - 1):
    gdf.iloc[[i]] = overlay(gdf.iloc[[i]], gdf.iloc[[i + 1]], how="difference")
```

#### Expected Output

No TypeError.

#### Output of ``geopandas.show_versions()``

<details>

Failed `CDLL(libgeos_c.so.1)`
Failed `CDLL(libgeos_c.so)`

SYSTEM INFO
-----------
python     : 3.9.5 (default, May 11 2021, 08:20:37)  [GCC 10.3.0]
executable : /home/username/Documents/project_name/env/bin/python
machine    : Linux-5.11.0-18-generic-x86_64-with-glibc2.33

GEOS, GDAL, PROJ INFO
---------------------
GEOS       : None
GEOS lib   : None
GDAL       : 3.3.0
GDAL data dir: /home/username/Documents/project_name/env/lib/python3.9/site-packages/fiona/gdal_data
PROJ       : 8.0.1
PROJ data dir: /home/username/Documents/project_name/env/lib/python3.9/site-packages/pyproj/proj_dir/share/proj

PYTHON DEPENDENCIES
-------------------
geopandas  : 0.9.0
pandas     : 1.2.4
fiona      : 1.8.20
numpy      : 1.20.3
shapely    : 1.7.1
rtree      : 0.9.7
pyproj     : 3.1.0
matplotlib : 3.4.2
mapclassify: None
geopy      : 2.1.0
psycopg2   : None
geoalchemy2: None
pyarrow    : None
pygeos     : None

</details>



Discussion:
Thanks for the report! I can confirm that this is a bug in the way how GeometryArray handles gdf (it does not :)).

I think we need to add one more condition handling this situation here:
https://github.com/geopandas/geopandas/blob/cb88dd4a9100bb990f6eb9b286e1ef3a0b185e3c/geopandas/array.py#L371

Would you like to try to fix it?
> Would you like to try to fix it?

Sure!  👍🏼

Thanks! Just give us a shout here if you'll need any guidance.
@JoakimJoensuu, do you plan to work on this issue? If no, I want to try to fix
> @JoakimJoensuu, do you plan to work on this issue? If no, I want to try to fix

@Akylzhan Yes, but don't know when. I have been too lazy to start. 😄 If you want to do the fix, then go ahead!

Resolving patch:
diff --git a/geopandas/array.py b/geopandas/array.py
--- a/geopandas/array.py
+++ b/geopandas/array.py
@@ -375,6 +375,8 @@ def __setitem__(self, key, value):
             key = pd.api.indexers.check_array_indexer(self, key)
         if isinstance(value, pd.Series):
             value = value.values
+        if isinstance(value, pd.DataFrame):
+            value = value.values.flatten()
         if isinstance(value, (list, np.ndarray)):
             value = from_shapely(value)
         if isinstance(value, GeometryArray):


Test patch:
diff --git a/geopandas/tests/test_array.py b/geopandas/tests/test_array.py
--- a/geopandas/tests/test_array.py
+++ b/geopandas/tests/test_array.py
@@ -761,6 +761,29 @@ def test_getitem():
     assert P5.equals(points[1])
 
 
+@pytest.mark.parametrize(
+    "item",
+    [
+        geopandas.GeoDataFrame(
+            geometry=[shapely.geometry.Polygon([(0, 0), (2, 0), (2, 2), (0, 2)])]
+        ),
+        geopandas.GeoSeries(
+            [shapely.geometry.Polygon([(0, 0), (2, 0), (2, 2), (0, 2)])]
+        ),
+        np.array([shapely.geometry.Polygon([(0, 0), (2, 0), (2, 2), (0, 2)])]),
+        [shapely.geometry.Polygon([(0, 0), (2, 0), (2, 2), (0, 2)])],
+        shapely.geometry.Polygon([(0, 0), (2, 0), (2, 2), (0, 2)]),
+    ],
+)
+def test_setitem(item):
+    points = [shapely.geometry.Point(i, i) for i in range(10)]
+    P = from_shapely(points)
+
+    P[[0]] = item
+
+    assert isinstance(P[0], shapely.geometry.Polygon)
+
+
 def test_equality_ops():
     with pytest.raises(ValueError):
         P[:5] == P[:7]