setting geometry with .loc from column value
See original GitHub issue-
I have come across an issue that crops up when attempting to set
geometryvalues with.locusing the values from another column. Using.locto set geometry works normally when setting with the index value, but throws an error (see the MWE/traceback below) otherwise. I don’t think this is expected behavior, but I could be very wrong. -
Being able to set geometry from a non-index column value is critical for a specific workflow I am using, so for an interim solution I ginned up a super hacky method for teasing out the index value based on a column value to allow for using
.loc. -
The error is actually being thrown from
pandas, but only seems to be happening withshapely.geometrytype objects so I wasn’t sure ifgeopandaswas the correct place to post this, but I figured it would be a safe start. -
Version info:
platform - 'Darwin-17.7.0-x86_64-i386-64bit'
python - '3.6.6 | packaged by conda-forge | (default, Jul 26 2018, 09:55:02)
'[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]'
geopandas - '0.4.0'
pandas - '0.23.4'
shapely - '1.6.4.post1'
MWE
In [1]: gdf = gpd.GeoDataFrame()
In [2]: line_1 = LineString(((0,0), (1,1)))
In [3]: line_2 = LineString(((3,3), (5,5)))
In [4]: gdf['geometry'] = [line_1]
In [5]: gdf['line_id'] = '999'
In [6]: print(gdf)
geometry line_id
0 LINESTRING (0 0, 1 1) 999
In [7]: print(gdf.loc[(gdf['line_id'] == '999'), 'geometry'])
0 LINESTRING (0 0, 1 1)
Name: geometry, dtype: object
[Fail] Attempt to set geometry value by the location of (gdf['line_id'] == '999')
In [8]: gdf.loc[(gdf['line_id'] == '999'), 'geometry'] = line_2
ValueError Traceback (most recent call last)
<ipython-input-154-8d7c73a5b6c8> in <module>()
----> 1 gdf.loc[(gdf['line_id'] == '999'), ['geometry']] = line2
~/miniconda3/envs/py3_at1866/lib/python3.6/site-packages/pandas/core/indexing.py in __setitem__(self, key, value)
187 key = com._apply_if_callable(key, self.obj)
188 indexer = self._get_setitem_indexer(key)
--> 189 self._setitem_with_indexer(indexer, value)
190
191 def _validate_key(self, key, axis):
~/miniconda3/envs/py3_at1866/lib/python3.6/site-packages/pandas/core/indexing.py in _setitem_with_indexer(self, indexer, value)
649 self.obj._consolidate_inplace()
650 self.obj._data = self.obj._data.setitem(indexer=indexer,
--> 651 value=value)
652 self.obj._maybe_update_cacher(clear=True)
653
~/miniconda3/envs/py3_at1866/lib/python3.6/site-packages/pandas/core/internals.py in setitem(self, **kwargs)
3691
3692 def setitem(self, **kwargs):
-> 3693 return self.apply('setitem', **kwargs)
3694
3695 def putmask(self, **kwargs):
~/miniconda3/envs/py3_at1866/lib/python3.6/site-packages/pandas/core/internals.py in apply(self, f, axes, filter, do_integrity_check, consolidate, **kwargs)
3579
3580 kwargs['mgr'] = self
-> 3581 applied = getattr(b, f)(**kwargs)
3582 result_blocks = _extend_blocks(applied, result_blocks)
3583
~/miniconda3/envs/py3_at1866/lib/python3.6/site-packages/pandas/core/internals.py in setitem(self, indexer, value, mgr)
938 # set
939 else:
--> 940 values[indexer] = value
941
942 # coerce and try to infer the dtypes of the result
ValueError: shape mismatch: value array of shape (2,2) could not be broadcast to indexing result of shape (1,1)
[Pass] Attempt to set geometry value by index location
In [9]: gdf.loc[0, 'geometry'] = line_2
In [10]: print(gdf)
geometry line_id
0 LINESTRING (3 3, 5 5) 999
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (6 by maintainers)

Top Related StackOverflow Question
I would say so, yes. I think it somehow related to the fact that
np.array(LineString(((0,0), (1,1), (1,3), (2,3), (4,5))))returns array of coordinates, but that is just a guess. Thanks!migrated to pandas-dev/pandas#28924