Remove a record from shapefile with python

2.8k Views Asked by At

I have an ESRI shapefile .shp (with all associated files like .shx, .dbf and many more) which I want to edit - I need to remove the first record and save the file.

For this purpose I installed pyshp and tried to parse and edit the shapefile. This is what I have tried:

import shapefile
e = shapefile.Editor('location/of/my/shp')
e.shapes()
# example output
>>> [<shapefile._Shape instance at 0x7fc5e18d93f8>,
     <shapefile._Shape instance at 0x7fc5e18d9440>,
     <shapefile._Shape instance at 0x7fc5e18d9488>,
     <shapefile._Shape instance at 0x7fc5e18d94d0>,
     <shapefile._Shape instance at 0x7fc5e18d9518>]

From here I want to delete the first entry <shapefile._Shape instance at 0x7fc5e18d93f8> and then save the file:

e.delete(0) # I tried e.delete(shape=0) too
e.save()

However the record is still available in the newly saved file.

Unfortunately the documentation doesn't go in depth about these things.

How can I accomplish my goal? How to check that the deletion has been successful before saving the file?

2

There are 2 best solutions below

3
On BEST ANSWER

I'm not familiarized with pyshp but this can be easily solved using ogr, which allows to work with vector data and makes part of the gdal library.

from osgeo import ogr

fn = r"file.shp"  # The path of your shapefile
ds = ogr.Open(fn, True)  # True allows to edit the shapefile
lyr = ds.GetLayer()

print("Features before: {}".format(lyr.GetFeatureCount()))
lyr.DeleteFeature(0)  # Deletes the first feature in the Layer

# Repack and recompute extent
# This is not mandatory but it organizes the FID's (so they start at 0 again and not 1)
# and recalculates the spatial extent.
ds.ExecuteSQL('REPACK ' + lyr.GetName())
ds.ExecuteSQL('RECOMPUTE EXTENT ON ' + lyr.GetName())

print("Features after: {}".format(lyr.GetFeatureCount()))

del ds
5
On

Following exactly the procedure you have described seems to work just fine for me. I start by opening a shapefile:

>>> e = shapefile.Editor('example')

This file has three shapes:

>>> e.shapes()
[<shapefile._Shape instance at 0x7f6cb5f67dd0>, <shapefile._Shape instance at 0x7f6cb5f67f38>, <shapefile._Shape instance at 0x7f6cb5f6e050>]

I delete the first shape and save the file:

>>> e.delete(0)
>>> e.save('example')

Now I re-open the file:

>>> e = shapefile.Editor('example')

And I can see that it now has only two shapes:

>>> e.shapes()
[<shapefile._Shape instance at 0x7f6cb5f6e518>, <shapefile._Shape instance at 0x7f6cb5f6e560>]