Geographic Information Systems Asked by Monitotier on January 4, 2021
I am working with ArcPy under Python 2.7.
I have a bunch of shapefiles that have the same structure.
I want to iterate through all of them to add a field (A1_norm
) and filling it with the multiplications of (A1
) by its ( mean= 2
). This will be repeated for (A2
)
The expected result would be something like this:
A A_norm
1 0.5
2 1
3 1.5
To do so, I have developed several options of code:
First approach
#setting the workspace
env.workspace = r'C:Users..'
# creating a list of features
listC = arcpy.ListFeatureClasses('*', 'all')
# adding the list of fields to a (list)
fieldlist = arcpy.ListFields('myShape.shp')
# Checking list all the fields of the feature/shape
for field in fieldlist:
print(field.name, field.type)
For which I get:
(u'FID', u'OID')
(u'Shape', u'Geometry')
(u'Id', u'Integer')
(u'A1', u'Double') #target field
(u'A2', u'Double') # target field
I define my formula:
def calculate_mean_value(table, field):
na = arcpy.da.TableToNumPyArray(table, field)
return np.mean(na[field])
# loop for calculating the mean of all the fields of the features listed on the env
for a in listC:
for field in fieldlist:
print (a, field.name, calculate_mean_value(a,field.name))
This works, but if I want to adapt the code to get the mean of my target fields:
# storing the field names in a list
field_namesT = [f.name for f in arcpy.ListFields('myShape.shp')if f.name.startswith('A')]
#trying to calculate the mean for the 2 targeted fields:
for a in listC:
for field in field_namesT:
print (a, field.name, calculate_mean_value(a,field.name))
The error:
AttributeError: 'unicode' object has no attribute 'name'
Second approach:
# setting the work space
env.workspace = r'C:Users..'
expression= calculate_mean_value(field.name)
#First, create the fieldlist with a loop for. With this I'll create the table
# these are the new fields that are going to be added to the shapefile
fieldlist1 = ["A1_Norm","A2_Norm"]
for field in fieldlist1:
arcpy.AddField_management('myShape.shp',field,"DOUBLE")
#And now calculate fields
arcpy.CalculateField_management('myShape.shp',"A1_Norm","!A1!/(sum(!A1!)/len(!A1!))!","PYTHON")
arcpy.CalculateField_management('myShape.shp',"A2_Norm","!A2!/(sum(!A2!)/len(!A2!))!","PYTHON")
The error:
ExecuteError: ERROR 000539: Error running expression: 0.690857157697 /np.mean(0.690857157697)
Traceback (most recent call last):
File "<expression>", line 1, in <module>
NameError: name 'np' is not defined
Failed to execute (CalculateField).
Third approach:
# setting the work space
env.workspace = r'C:Users'
# Set local variables
shape = 'myShape.shp'
fieldT = 'A1'
expression = 'fieldT/calculate_mean_value(shape, fieldT)'
fieldR ='A1_Norm'
codeblock = """
def calculate_mean_value(shape, fieldT):
na = arcpy.da.TableToNumPyArray(shape, fieldT)
return np.mean(na[fieldT])"""
# Execute AddField
arcpy.AddField_management(shape, fieldR, "DOUBLE")
# Execute CalculateField
arcpy.CalculateField_management(shape, fieldR, expression,"PYTHON", codeblock)
The error:
ExecuteError: ERROR 000539: Error running expression: fieldT/calculate_mean_value(shape, fieldT)
Traceback (most recent call last):
File "<expression>", line 1, in <module>
NameError: name 'fieldT' is not defined
Failed to execute (CalculateField).
Can anyone give me a hint of how to solve this issue?
The following approach calculates the mean of A
and writes the value of A * mean(A)
in the A_norm
field.
import arcpy
arcpy.env.workspace = '/path/to/your/workspace'
fcs = arcpy.ListFeatureClasses()
for fc in fcs:
# Add "A_norm" field
arcpy.AddField_management(fc, "A_norm", "DOUBLE")
# Find mean of A
vals = [row[0] for row in arcpy.da.SearchCursor(fc, "A")]
mean = sum(vals)/len(vals)
# Calc field
with arcpy.da.UpdateCursor(fc, ("A", "A_norm")) as cursor:
for row in cursor:
row[1] = row[0] * mean
cursor.updateRow(row)
Correct answer by Aaron on January 4, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP