16

I am using GeoPandas in python and have a valid GeoDataframe of polygons.

0         POLYGON Z ((68.70999999999999 623.1 0, 35.71 6...
1         POLYGON Z ((221.33 645.02 0, 185.7 640.33 0, 1...
2         POLYGON Z ((150.3 650 0, 160.9 650 0, 150.58 6...

I want to obtain a new dataframe that has the bounding box coordinates for each row in the dataframe.

Now I am getting some odd behavior for GeoPandas.

Say I name the GeoDataFrame gdf, then using the code:

gdf.bounds

I get the corresponding error. I have no clue what this error is supposed to mean, since I did not pass any values into the bounds method--they were passed implicitly.

ValueError: Shape of passed values is (1, 110042), indices imply (4, 110042)

When I try: gdf.geometry.bounds I get the same ValueError...

However, when I do it this way, I get a valid answer:

gdf.head(10).bounds

I get

    minx    miny    maxx    maxy
0   0.00    618.15  68.71   650.00
1   169.56  640.33  221.33  650.00
2   150.30  648.64  160.90  650.00

So gdf and gdf.head() are not any different, yet one gives me an error and one does not. Does anyone know the correct way to get the bounding boxes corresponding to each row.

krishnab
  • 9,270
  • 12
  • 66
  • 123
  • 2
    gdf.bounds works fine for me (in 2D)... Did you try to change your dataset ? – tgrandje May 02 '18 at 14:16
  • 2
    I figured out the problem. So basically when the `bounds` method encountered an empty polygon, that is a polygon win wkt "POLYGON EMPTY" then it would crash with this error. Now I think that the POLYGON EMPTY is a valid wkt string, but it was giving me this ValueError. So after I filtered out these empty polygons, then it worked as expected. – krishnab May 02 '18 at 22:31
  • 1
    @krishnab would you mind writing your above comment as an answer to this question, so that it no longer shows up as "unanswered"? Thanks! – dericke Nov 12 '20 at 18:18
  • @dericke thanks for the tip. Yeah, I can actually fill in the details in an answer. No problem. Thanks again. – krishnab Nov 12 '20 at 20:21

1 Answers1

2

You can also try the following

# remove empty geometry
valid_geom = gdf[gdf.geometry.map(lambda z: True if not z.is_empty else False)]
# get the bounds of each geometry
valid_geom.geometry.map(lambda z: z.exterior.xy)

# or in one line
gdf[gdf.geometry.map(lambda z: True if not z.is_empty else False)].geometry.map(lambda z: z.exterior.xy)

This would result in the following output. you get (minx, miny, maxx, maxy) as a list.

0     ([346494.47052450513, 346512.1633455531, 34642...
1     ([347156.6195963654, 347140.5694171803, 347106...
2     ([347374.2493280142, 347343.280266067, 347331....
3     ([347752.9399173185, 347732.0804000348, 347699...
4     ([352462.7065634858, 352421.82634455897, 35239...
5     ([352398.84073305037, 352366.62657852937, 3523...
6     ([351619.2911484046, 351581.3489685701, 351559...
7     ([349298.04394918215, 349284.4299869118, 34926...
8     ([349402.6562116009, 349390.3714050767, 349364...
9     ([347447.35067824554, 347427.2888365253, 34740...
10    ([351038.9227137904, 351023.75894022046, 35101...
11    ([352360.8991716495, 352311.8060843693, 352289...
12    ([348053.8637179602, 348014.5578245763, 347995...
13    ([350854.3664365387, 350802.39711500367, 35075...
14    ([350661.291738528, 350539.01532645256, 350497...
15    ([349634.9936554617, 349617.43041924713, 34959...
16    ([346588.703008323, 346576.2541223159, 346560....
17    ([347323.7364982413, 347311.6537559405, 347289...
18    ([347592.9326738138, 347588.24603437353, 34757...
19    ([347871.4965194545, 347852.9032783319, 347846...
20    ([349503.7927385038, 349484.6946827946, 349482...
21    ([349917.505834857, 349907.19522809517, 349885...
22    ([350254.82670837734, 350243.1101097837, 35024...
dtype: object
Aman Bagrecha
  • 406
  • 4
  • 9