8

Is it possible to update an attribute field in a shapefile using pyshp ?

I went through their documentation and all they show is how to create new attribute rather than editing or updating an already existing one.

If updating is not possible, is there any other recommended Python library for doing the same ?

Devdatta Tengshe
41.8k37 gold badges147 silver badges267 bronze badges
asked Apr 10, 2013 at 6:00
1
  • 1
    Do you have a sample shape file? Commented Apr 10, 2013 at 13:49

4 Answers 4

20

It is the same thing with pyshp, except that you cannot update directly the dbf file. When you read a shapefile, the data are stored in Python lists

import shapefile
input = shapefile.Reader("yourfile.shp")
shapes = input.shapes() # -> the geometries in a list
fields = input.fields[1:] # -> the fields definition in a list
fields_name = = [field[0] for field in fields] # -> the fields names in a list
attributes = input.records() # -> the attributes in a list
# now you can modify an attribute value in the list:
attributes[0][1] = "what you want" # second attribute of the first record
# if you want to use a field name for the attribute, like in dbfpy, you must use a dictionary
list = [(i,dict(zip(fields, attri))) for i,attri in enumerate(attributes)]
dict = dict((key, value) for (key, value) in list)
# now you can modify an attribute value in the dictionary:
dict[0]['field']='whatyouwant' # attribute of "field" in the first record
# and return to the original attributes list
attributes_cor = [i.values() for i in dict.values()]

but this changes the value in the list or in the dictionary, not in the dbf file. To do this, rather than affecting the original shapefile, it is better to create a copy with the new attribute list (same as Add a Field to an Existing Shapefile or Subsetting a Shapefile by Attributes ).

You can also use other Python libraries like ogr or Fiona (see Using the API of QSpatiaLite plugin for the principles, the data are stored as Python dictionaries)

from shapely.geometry import mapping, shape
import fiona
# Read the original Shapefile
with fiona.collection('yourfile.shp', 'r') as input:
# The output has the same schema
schema = input.schema.copy()
# write a new shapefile
with fiona.collection('yourcopyfile.shp', 'w', 'ESRI Shapefile', schema) as output:
 for elem in input:
 elem['properties']['field'] = 'whatyouwant' # or a function, or...
 output.write({'properties': elem['properties'],'geometry': mapping(shape(elem['geometry']))})
answered Apr 10, 2013 at 16:58
1
  • 1
    +1 I was gonna write about using Fiona/OGR too but I don't know enough about it so I went with dbfpy. Thanks for your detailed answer :) Commented Apr 12, 2013 at 8:25
8

I'm the author of PyShp. Both R.K. and Gene are correct. Editing a file like a dbf is just an illusion. What you are really doing is reading in the old one into a Python object, changing some variable values, and writing over the old file.

If you are going to do a bunch of dbf editing definitely use dbfpy. Like PyShp it is pure python but has more robust dbf capabilities than PyShp and a richer API for "editing".

The blog posts that Gene references shows how to read, change, and save a shapefile in PyShp which is what dbfpy is doing under the hood.

answered Apr 11, 2013 at 18:25
7

You can use dbfpy to directly access and edit the attributes in the shape file's dbf file.

from dbfpy import dbf
db = dbf.Dbf("your_file.dbf")
#Editing a value, assuming you want to edit the first field of the first record
rec = db[0]
rec["FIRST_FIELD"] = "New value"
rec.store()
del rec
db.close()
answered Apr 10, 2013 at 13:48
3

I had the same question and yes! you can update attributes using pyshp.

Here I show you an example:

import shapefile
import pprint as p
def modify(key,value,e):
 for i in range(len(e.records)):
 if(e.records[i][0]==key):
 e.records[i][2]=value
 break
def editShape():
 e = shapefile.Editor("/home/agus/Desktop/converterPy/provicias/provinces800.shp")
 p.pprint(e.records[1])
 p.pprint(e.records[3])
 p.pprint(e.records[7])
 modify("Antofagasta",1,e)
 modify("Tocopilla",23,e)
 modify("Huasco",90,e)
 print("--------- AFTER EDIT ---------")
 p.pprint(e.records[1])
 p.pprint(e.records[3])
 p.pprint(e.records[7])
 e.save("/home/agus/Desktop/converterPy/provicias/provinces800.shp")
editShape()

If you run this file this is the result:

['Antofagasta', 'AT', 0]
['Tocopilla', 'TO', 0]
['Huasco', 'HU', 0]
--------- AFTER EDIT ---------
['Antofagasta', 'AT', 1]
['Tocopilla', 'TO', 23]
['Huasco', 'HU', 90]

This overwrite the original shapefile so be carefully.

whyzar
12.1k23 gold badges41 silver badges72 bronze badges
answered Dec 9, 2016 at 9:51

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.