|
POST
|
Hi Mark, I have some observations on the code you posted, since there some potential errors in the code: By using the keyword "CURRENT", the code can only be run inside the MXD (from for instance the Python window) and cannot be used as standalone code. You are setting the workspace as "CURRENT". I don't think this is a keyword that can be used for the "current workspace", but the code does not have any parts that require setting the workspace. You are looping through each layer and actually doing the same thing for each layer. The only thing that is influenced is that each time you move to a lower layer this layer is switched on (if it wasn't in the first place). Is this really what you want? What is really an issue is using a count and setting the whereclause for the searchcursor and the select by attribute, based on the assumption that the FID contains sequential numbers and no gaps. When you edit a featureclass and eliminate a feature and add another the sequence will have a gap. Please be aware of that. In case you have polygons that share boundaries, when exporting the polygon, you will see that polygon next to it if it falls within the exporting extent. This can be prevented setting a definition query. Using a search cursor (and preferably the arcpy.da.SearchCursor) allows you to create a more powerful script that will have less chances to fail. So based on what I described above I would suggest using code like this:
import arcpy, os
def getLayerOnName(mxd, lyr_name):
for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.name.upper() == lyr_name.upper():
return lyr
break
# some settings and variables
mxd_path = "CURRENT" # or use a path to the mxd file
df_name = "Layers"
lyr_name = "Grid"
fld_id = "FID" # "Name of the field that has a unique number for the output files"
jpg_folder = r"C:\Temp"
jpg_prefix = "Map_"
show_only_current_polygon = True
mxd = arcpy.mapping.MapDocument(mxd_path)
df = arcpy.mapping.ListDataFrames(mxd, df_name)[0]
lyr = getLayerOnName(mxd, lyr_name)
lyr_ds = lyr.dataSource
# loop through all features
flds = ("SHAPE@", fld_id)
with arcpy.da.SearchCursor(lyr_ds, flds) as curs:
for row in curs:
pol_ext = row[0].extent
pol_id = row[1]
# set a whereclause
if show_only_current_polygon:
wc = "{0} = {1}".format(arcpy.AddFieldDelimiters(lyr_ds, fld_id), pol_id)
lyr.definitionQuery = wc
df.extent = pol_ext
jpg_name = "{0}{1}.jpg".format(jpg_prefix, pol_id)
jpg_path = os.path.join(jpg_folder, jpg_name)
arcpy.mapping.ExportToJPEG(mxd, jpg_path, df, df_export_width=3004,
df_export_height=2125, world_file=True)
print "Exported: {0}".format(jpg_name)
What happens in this code is: Lines 3 - 7 defines a function that returns the layer you're interested in based on the name of the layer (as displayed in the TOC) Lines 10 - 16 are used to define some settings (names of mxd, layer, dataframe, output folder, prefix for the jpg and to define if the current polygon is the only polygon that should be showed (for that layer) Lines 18 - 21 reads the mxd, the dataframe the layer and reads the datasource of the layer (you could use the layer itself for the search cursor, but if not all the features are displayed {e.g. a definition query is set} this will affect the number of features processed) Line 24 - 26 the search cursor is defined and the loop is started Line 27 and 28 read the extent of the polygon and the unique id for that polygon Line 31 - 33 will set the definition query to only show the current polygon (if show_only_current_polygon is set to True) Line 35 sets the extent of the dataframe Line 36 - 37 defines the output file name Line 38 - 39 exports the jpg Line 41 prints the process Give it a shot and see if it works... Kind regards, Xander
... View more
08-02-2014
08:11 PM
|
2
|
0
|
2220
|
|
POST
|
If you look at the thread on stack overflow: portability - Is there a portable way to get the current username in Python? - Stack Overflow ... there are some examples provided to get the current user name which worked on my system (Windows 8.1, Python 2.7):
import os
print os.environ["USERNAME"]
print os.path.split(os.path.expanduser('~'))[-1]
import getpass
print getpass.getuser()
They all printed my current user name. Kind regards, Xander
... View more
08-02-2014
06:12 PM
|
1
|
1
|
1731
|
|
POST
|
Hi Ian Murray and Inception Woznicki, I would probably still use dictionaries. They provide a flexible way of processing this kind of problems. Take a look at the code below (please note that I did not test the code, so I am sure there will still be some errors in it).
import arcpy, os
#Set environment settings
arcpy.env.overwriteOutput = True
arcpy.env.workspace = "C:/Subhasis/Project-06-02-14/Landuse/New folder/Merged/Landuse_raster"
# you're not use this workspace in your code, but I suppose you eventually will.
# outws="C:/Subhasis/Project-06-02-14/Landuse/New folder/Merged/Landuse_raster/Table"
# configuration of lists of values
lst_agr = [2100, 2200, 2300, 2400] # agriculture
lst_bar = [7100, 7200, 7300, 7400, 7500, 7600] # Barren Land
lst_for = [4110, 4120, 4210, 4220, 4230, 4311, 4312, 4321, 4322, 4410] # Forest
lst_urb = [1110, 1120, 1130, 1140, 1150, 1200, 1211, 1214, 1300, 1400,
1410, 1411, 1420, 1440, 1462, 1463, 1499, 1500, 1600, 1700,
1710, 1741] # Urban
lst_wat = [1419, 5100, 5190] # Water
lst_wet = [1461, 1711, 1750, 1850] # Wetlands
# Create a dictionary with the classname vs the lists
dct_lsts = {"Agriculture": lst_agr, "Barren Land": lst_bar,
"Forest": lst_for, "Urban": lst_urb,
"Water": lst_wat, "Wetlands": lst_wet}
# optionally, divide the Urban area further into 4 categories.
# instead of creating 1 list, create 4 separate lists, like this:
##lst_urb1 = [1110, 1120, 1130, 1140, 1150, 1200]
##lst_urb2 = [1211, 1214, 1300, 1400, 1410, 1411]
##lst_urb3 = [1420, 1440, 1462, 1463, 1499, 1500]
##lst_urb4 = [1600, 1700, 1710, 1741]
##dct_lsts = {"Agriculture": lst_agr, "Barren Land": lst_bar,
## "Forest": lst_for, "Urban 1": lst_urb1,
## "Urban 2": lst_urb2, "Urban 3": lst_urb3,
## "Urban 4": lst_urb4, "Water": lst_wat,
## "Wetlands": lst_wet }
# loop through rasters
flds = ("VALUE", "COUNT")
lst_ras = arcpy.ListRasters("*", "GRID")
for ras in lst_ras:
# create dct with value vs count for this raster:
dct = {row[0]:row[1] for row in arcpy.da.SearchCursor(ras, flds)}
# now create an initial dictionay that will hold the resulting counts per LU class
dct_res = {lu: 0 for lu in dct_lsts.keys()}
# now fill the resulting dictionary
for val, cnt in dct.items():
# determine the lu class and add count
for lu, lst in dct_lsts.items():
if val in lst:
dct_res[lu] += cnt
break
# now print the result:
print "\nLanduse statistics for raster: '{0}'".format(ras)
for lu, cnt in dct_res:
print " - {0}: {1}".format(lu, cnt)
This is what happens (if the code works): On lines 11 - 18 lists of the values corresponding to a landuse class are created On Lines 21 - 23 a dictionary is created that uses a landuse description as key and the list of values is the value assigned to the key On Line 28 - 37 (commented) an example is shown how you could incorporate subdividing urban into 4 classes (the values assigned to each class is arbitrary) I placed the line 41 outside the loop, since assigning it one time is enough On line 42 - 43, a list of GRID rasters is created and the loop is started Line 45 creates the dictionary with pixelvalues vs count for the current raster Line 48 creates an initial dictionary with the landuse name as key and the count set to 0 Line 51 starts a loop through the pixel values vs count of the current raster Line 53, with that loop another loop is started to go through the dictionary with the lists. On line 54 a check is done to see of the current pixelvalue is inside the current list of pixel values for the current land use. If the is the case, the count is added to the count in the dictionary that holds the landuse class description vs the count This is followed by a break to step out of the inner loop (the one that goes through each landuse class and list of related pixel values) Lines 59 - 61 should create a list per raster with each landuse class and the calculated count. Writing this down, I think you could also create a reference table with the pixelvalues on each row and the corresponding landuse classname in another column and join this table to the attribute table of the raster and perform a summerize on the landuse class column, summing the count... Kind regards, Xander
... View more
08-01-2014
05:46 PM
|
1
|
1
|
2990
|
|
POST
|
OK, so far for posting code without testing it ... I created a small test dataset, consisting of a DEM (integer raster) and some random polygons. During the test a number of errors in the code were revealed. These are corrected in the code below:
def GetPixelValueForPercentile(dctper, percentile):
"""will return last pixel value
where percentile LE searched percentile."""
for k in sorted(dctper.keys()):
perc = dctper
if perc <= percentile:
pix_val = k
else:
break
return pix_val
def FieldExist(featureclass, fieldname):
"""Check if field exists"""
import arcpy
fieldList = arcpy.ListFields(featureclass, fieldname)
return len(fieldList) == 1
import arcpy
# settings
ras = r"D:\Xander\tmp\ras.gdb\DEMsmpro"
fc = r"D:\Xander\tmp\ras.gdb\pols"
# ras = r"C:\Path\To\Folder\Or\Geodatabase\With\Raster"
# fc = r"C:\Path\To\Folder\Or\Geodatabase\With\PolygonFeatureclass"
lst_perc = [2, 5, 10, 90, 95, 98] # list of percentiles to be calculated
fld_prefix = "Perc_"
arcpy.env.workspace = "IN_MEMORY"
arcpy.env.overwriteOutput = True
# add fields if they do not exist in fc
# be aware, field that exist will be overwritten!
print "filling field list and adding fields"
flds = []
for perc in lst_perc:
fld_perc = "{0}{1}".format(fld_prefix, perc)
flds.append(fld_perc)
if not FieldExist(fc, fld_perc):
arcpy.AddField_management(fc, fld_perc, "LONG")
print "flds={0}".format(flds)
# Enable Spatial analyst
arcpy.CheckOutExtension("Spatial")
# loop through polygons
print "loop through polygons"
flds.append("SHAPE@")
i = 0
with arcpy.da.UpdateCursor(fc, flds) as curs:
for row in curs:
i += 1
print "Processing polygon: {0}".format(i)
polygon = row[flds.index("SHAPE@")]
lst_parts = []
if polygon.partCount == 1:
for part in polygon:
for pnt in part:
x, y = pnt.X, pnt.Y
lst_parts.append(arcpy.Point(x, y))
else:
for part in polygon:
lst_crds = []
for pnt in part:
x, y = pnt.X, pnt.Y
lst_crds.append(arcpy.Point(x, y))
lst_parts.append(lst_crds)
print " - lst_parts={0}".format(lst_parts)
# Execute ExtractByPolygon (you can't send the polygon object)
print " - ExtractByPolygon..."
ras_pol = arcpy.sa.ExtractByPolygon(ras, lst_parts, "INSIDE")
outname = "ras{0}".format(i)
ras_pol.save(outname)
print " - saved raster as {0}".format(outname)
# create dictionary with value vs count
print " - fill dict with Value x Count"
flds_ras = ("VALUE", "COUNT")
dct = {row[0]:row[1] for row in arcpy.da.SearchCursor(outname, flds_ras)}
# calculate number of pixels in raster
print " - determine sum"
cnt_sum = sum(dct.values())
print " - sum={0}".format(cnt_sum)
# loop through dictionary and create new dictionary with val vs percentile
print " - create percentile dict"
dct_per = {}
cnt_i = 0
for val in sorted(dct.keys()):
cnt_i += dct[val]
dct_per[val] = cnt_i / cnt_sum
# loop through list of percentiles
print " - iterate perceniles"
for perc in lst_perc:
# use dct_per to determine percentiles
perc_dec = float(perc) / 100
print " - Perc_dec for is {0}".format(perc_dec)
pixval = GetPixelValueForPercentile(dct_per, perc_dec)
print " - Perc for {0}% is {1}".format(perc, pixval)
# write pixel value to percentile field
print " - Store value"
fld_perc = "{0}{1}".format(fld_prefix, perc)
row[flds.index(fld_perc)] = pixval
# update row
print " - update row"
curs.updateRow(row)
# return SA license
arcpy.CheckInExtension("Spatial")
What you get are a number of fields in your polygon featureclass: When you add some labels to display the values, you'll see that they actually correspond to the areas: So Todd, I hope this will work for you. Kind regards, Xander
... View more
07-30-2014
06:25 AM
|
5
|
44
|
9439
|
|
POST
|
Hi Todd, One option is that you write a loop through the polygon (Update cursor) to do this for each polygon: use the arcpy.sa.ExtractByPolygon tool to extract the relevant portion of raster and save that to the IN_MEMORY workspace use that raster and the previous posted code to determine the percentiles define a list of percentile values like lst_prec = [2, 5,10, 90, 95, 98] to loop through the values and determine the raster value that corresponds to that percentile. Store the result in previously created fields. In case there is no overlap between the polygons, you could do the following: Rasterize your polygon layer Use the arcpy.sa.Combine tool to create a raster that holds the combination of both values. If the number of unique combinations is less than 65536, this should be no problem. Adapt the code to read both the polygon layer in an update cursor and the combine raster attribute table in a search cursor to determine the percentiles and store the result Not sure which option will be the fastest. Now to throw in some code (which by the way I did not test), it should look something like this:
def GetPixelValueForPercentile(dctper, percentile):
"""will return last pixel value
where percentile LE searched percentile."""
for k in sorted(dctper.keys()):
perc = dctper
if perc <= percentile:
pix_val = k
else:
break
return pix_val
def FieldExist(featureclass, fieldname):
"""Check if field exists"""
import arcpy
fieldList = arcpy.ListFields(featureclass, fieldname)
return len(fieldList) == 1
import arcpy
# settings
ras = r"C:\Path\To\Folder\Or\Geodatabase\With\Raster"
fc = r"C:\Path\To\Folder\Or\Geodatabase\With\PolygonFeatureclass"
lst_perc = [2, 5, 10, 90, 95, 98] # list of percentiles to be calculated
fld_prefix = "Perc_"
arcpy.env.workspace = "IN_MEMORY"
# add fields if they do not exist in fc
# be aware, field that exist will be overwritten!
flds = []
for perc in lst_perc:
fld_perc = "{0}{1}".format(fld_prefix, perc)
flds.append(fld_perc)
if not FieldExist(fc, fld_perc):
arcpy.AddField_management(fc, fld_perc, "LONG")
# Enable Spatial analyst
arcpy.CheckOutExtension("Spatial")
# loop through polygons
flds.append("SHAPE@")
with arcpy.da.UpdateCursor(fc, flds) as curs:
for row in curs:
polygon = row[flds.index("SHAPE@")]
lst_parts = []
for part in polygon:
lst_crds = []
for crdpair in part:
x, y = crdpair[0], crdpair[1]
lst_crds.append(arcpy.Point(x, y))
lst_parts.append(lst_crds)
# Execute ExtractByPolygon
ras_pol = arcpy.sa.ExtractByPolygon(ras, polygon, "INSIDE")
# not sure if ras_pol should be saved...
# create dictionary with value vs count
flds_ras = ("VALUE", "COUNT")
dct = {row[0]:row[1] for row in arcpy.da.SearchCursor(ras_pol, flds_ras)}
# calculate number of pixels in raster
cnt_sum = sum(dct.values())
# loop through dictionary and create new dictionary with val vs percentile
dct_per = {}
cnt_i = 0
for val in sorted(dct.keys()):
cnt_i += dct[val]
dct_per[val] = cnt_i / cnt_sum
# loop through list of percentiles
for perc in lst_perc:
# use dct_per to determine percentiles
prec_dec = float(perc) / 100
pixval = GetPixelValueForPercentile(dct_per, perc)
# write pixel value to percentile field
fld_perc = "{0}{1}".format(fld_prefix, perc)
row[flds.index(fld_perc)] = pixval
# update row
curs.updateRow(row)
# return SA license
arcpy.CheckInExtension("Spatial")
If you run into problems, let me know. Maybe you can throw in a piece of your data to test the code. Kind regards, Xander
... View more
07-29-2014
03:11 PM
|
1
|
45
|
9439
|
|
POST
|
Hi Lorraine, Try this code, it creates the same value you are expecting:
import arcpy
# fc = "D:/Xander/tmp/NIData.gdb/test_copy"
fc = "C:/Temp/lorraine/NIData.gdb/fc_f6000_in99Matx"
fld_id = "RegID_6k99"
fld_label = "FLABEL"
fld_flows = "RegIntFlows"
# create a unique list of all the FLABEL values
lst_labels = list(set([row[0] for row in arcpy.da.SearchCursor(fc, (fld_label))]))
# Create the list of fields to be used in the SearchCursor
flds = [fld_id, fld_label]
flds.extend(lst_labels)
# create list of all fields
flds_all = [fld.name for fld in arcpy.ListFields(fc)]
# make sure that the relevant fields for the SearchCursor exist in fc
flds = list(set(flds) & set(flds_all))
# create a dictionary with for each RegID_6k99 a list of corresponding FLABEL fields
dct_ref ={}
flds2 = (fld_id, fld_label)
with arcpy.da.SearchCursor(fc, flds2) as curs:
for row in curs:
uni_id = row[0]
lbl = row[1]
if uni_id in dct_ref:
lst_lbls = dct_ref[uni_id]
if not lbl in lst_lbls:
lst_lbls.append(lbl)
else:
lst_lbls = [lbl]
dct_ref[uni_id] = lst_lbls
# loop through data and fill the result dictionary
flds.append(fld_flows)
with arcpy.da.UpdateCursor(fc, flds) as curs:
for row in curs:
uni_id = row[flds.index(fld_id)]
if uni_id in dct_ref:
lst_lbls = dct_ref[uni_id]
val = 0
for lbl in lst_lbls:
if lbl in flds:
val += row[flds.index(lbl)]
else:
print " - lbl {0} in field FLABEL for RegID_6k99 = {1} does not exist as field".format(lbl, uni_id)
row[flds.index(fld_flows)] = val
curs.updateRow(row)
else:
print "key uni_id {0} not found in dct_ref".format(uni_id)
What has changed is this: lines 22 - 34 creates a dictionary with unique FLABELS per RegID_6k99 lines 37 - 52 the search cursor and update cursor have been replaced by a single update cursor. line 42 reads the list of FLABELS for the current RegID_6k99 lines 44 - 46 sums the relevant values line 49 stores the value in the flow field Kind regards, Xander
... View more
07-29-2014
07:49 AM
|
0
|
0
|
4524
|
|
POST
|
Hi Lorraine, What I understood is that the code should sum the values for all records for a RegID_6k99. That's why the result is higher than you expected. Based on what you are showing, it seems that the calculation should be affected for each row. This means that there is no need to have both the Search cursor and the Update cursor. A single Update cursor will do. Before I start with the changes in the code, let me get some things clear: in the image I suppose that cells A4 and D1 should be "F95XX11" in stead of "F92XX10". the example show all the records (3) for RegID_6k99 = 4 the FLABEL field for those 3 records contains the values F95XX01, F95XX10 and F95XX11 for each record those fields (F95XX01, F95XX10 and F95XX11) should be summed (in case RegID_6k99 = 4) If this is the case we will need to create an initial dictionary that stores the 1:n relation of RegID_6k99 and FLABEL. In the update cursor we will need to read this dictionary to determine which fields to sum. If this is what you are looking for, let me know and I'll dive into that. Kind regards, Xander
... View more
07-29-2014
07:19 AM
|
0
|
0
|
4524
|
|
POST
|
It is always a good thing to include the actual error message, since it helps us to determine the reason for which the error occurs. Another thing that would increase readability of the code, would be to use syntax highlighting. You can read more about this here: Posting Code blocks in the new GeoNet You do not have to import the sa module, nor is it necessary to check out a sa license. All the tools you are using are available at each license level without the need for any extension. I notice that you define the outPolygons by using ".shape" as extension. If you want to create a shapefile, you should specify ".shp" as extension. Kind regards, Xander
... View more
07-28-2014
10:59 AM
|
0
|
2
|
1294
|
|
POST
|
Hi Lorraine, Thanks for sending the dataset. This way I could test the code and noticed that I had quite a number of errors in the script. Please observe the corrected code that "did something" (you should verify if the values correspond to what you expected).
import arcpy
# fc = "D:/Xander/tmp/NIData.gdb/test_copy"
fc = "C:/Temp/lorraine/NIData.gdb/fc_f6000_in99Matx"
fld_id = "RegID_6k99"
fld_label = "FLABEL"
fld_flows = "RegIntFlows"
# create a unique list of all the FLABEL values
lst_labels = list(set([row[0] for row in arcpy.da.SearchCursor(fc, (fld_label))]))
# Create the list of fields to be used in the SearchCursor
flds = [fld_id, fld_label]
flds.extend(lst_labels)
# create list of all fields
flds_all = [fld.name for fld in arcpy.ListFields(fc)]
# make sure that the relevant fields for the SearchCursor exist in fc
flds = list(set(flds) & set(flds_all))
# loop through data and fill the result dictionary
dct_res = {}
with arcpy.da.SearchCursor(fc, flds) as curs:
for row in curs:
uni_id = row[flds.index(fld_id)]
lbl = row[flds.index(fld_label)]
if lbl in flds:
val = row[flds.index(lbl)]
if uni_id in dct_res:
dct_res[uni_id] += val
else:
dct_res[uni_id] = val
else:
# lbl in field FLABEL does not exist as field
pass
# now update the values with an update cursor and the result dictionary
flds = (fld_id, fld_flows)
with arcpy.da.UpdateCursor(fc, flds) as curs:
for row in curs:
row[1] = dct_res[row[0]]
curs.updateRow(row)
Some of the errors in the code where: line 13 I write "flds.extent()" when this should be "flds.extend()" line 16 has been changed. The ListFields returns field objects and not the field names. line changed to use a List Comprehension to generate the list of field names Line 30 and 32 referred to a variable called "dct_rec" in stead of "dct_res" Line 42 tried to do an updateRow on the row object when this should be called on the curs object At least I learned a thing that I shouldn't try to do these kind of things without a dataset... Hope this works for you. Kind regards, Xander
... View more
07-28-2014
09:07 AM
|
0
|
2
|
4524
|
|
DOC
|
Example of how you can use Numpy (Python) to write a dictionary to a new table
... View more
07-27-2014
08:27 PM
|
1
|
0
|
2760
|
|
POST
|
Hi Subhasis, I notice you have 5 separate threads on more or less the same topic: Inception Woznicki (just look at the content) I have a few recommendations: Concentrate on this topic: loop for value and counts in raster attribute is has the most answers. If there are helpful comments mark them as helpful, it will help other user to find useful content faster If a question was answered mark the thread as answered at the right comment, this also helps the community to find useful content, and avoids people to invest their time in your question, if your question was already solved. Kind regards, Xander
... View more
07-27-2014
07:46 PM
|
1
|
1
|
1646
|
|
POST
|
If this question is related to the rasters created in your thread Re: loop for value and counts in raster attribute, then Dan Patterson is absolutely right. The problem occurs in the line:
outname=os.path.join(outws,str(i), str(j))
This should be:
outname=os.path.join(outws,"{0}{1}".format(i,j))
The first creates an outname of: C:/Subhasis/Test/Neshanic_Python/extract\01367620-r-r\9 The second creates an outname of: C:/Subhasis/Test/Neshanic_Python/extract\01367620-r-r9 The os,path.join will place a slash between each parameter. This causes the value "j" to be the raster name and the value "i" is interpreted as folder. BTW: if the thread Re: loop for value and counts in raster attribute is solved, you should mark it as answered! Kind regards, Xander
... View more
07-27-2014
07:28 PM
|
0
|
1
|
1309
|
|
POST
|
actually.. if layer.name in dictionary_Layer: ... is enough, since it automatically checks for the keys...
... View more
07-27-2014
06:57 PM
|
0
|
0
|
2793
|
|
POST
|
Hi JD, To use the script in a toolbox with parameters, you have to adapt the script so it reads the parameters. See the Help on "Accessing parameters in a script tool": ArcGIS Help (10.2, 10.2.1, and 10.2.2) You will have to use the arcpy.GetParameterAsText() or arcpy.GetParameter() and arcpy.SetParameter() or arcpy.SetParameterAsText() to do so... Kind regards, Xander
... View more
07-27-2014
06:28 PM
|
0
|
0
|
1362
|
|
POST
|
Hi Lorraine, Please have a look at the code below:
import arcpy
fc = "C:/Temp/lorraine/NIData.gdb/fc_f6000_in99Matx"
fld_id = "RegID_6k99"
fld_label = "FLABEL"
fld_flows = "RegIntFlows"
# create a unique list of all the FLABEL values
lst_labels = list(set([row[0] for row in arcpy.da.SearchCursor(fc, (fld_label))]))
# Create the list of fields to be used in the SearchCursor
flds = [fld_id, fld_label]
flds.extent(lst_labels)
# create list of all fields
flds_all = arcpy.ListFields(fc)
# make sure that the relevant fields for the SearchCursor exist in fc
flds = list(set(flds) & set(flds_all))
# loop through data and fill the result dictionary
dct_res = {}
with arcpy.da.SearchCursor(fc, flds) as curs:
for row in curs:
uni_id = row[flds.index(fld_id)]
lbl = row[flds.index(fld_label)]
if lbl in flds:
val = row[flds.index(lbl)]
if uni_id in dct_res:
dct_rec[uni_id] += val
else:
dct_rec[uni_id] = val
else:
# lbl in field FLABEL does not exist as field
pass
# now update the values with an update cursor and the result dictionary
flds = (fld_id, fld_flows)
with arcpy.da.UpdateCursor(fc, flds) as curs:
for row in curs:
row[1] = dct_res[row[0]]
row.updateRow(row)
First of all I have not tested the code, so this might not work at all. If you are willing to attach a part of your data to this thread, I could test the code and tweak it where necessary... I'll try to explain what I intent to do in the code: on line 8, a unique list of all the values in the field FLABEL is created. This will be used later on to define the fields for the search cursor on line 11 and 12, the actual list of fields created (all the FLABEL values and the RegID_6k99 field and the FLABEL field) on line 15 a list of fields is created (all fields in the featureclass) on line 18 the list of fields (from line 12) is tested against the available fields in the featureclass on line 22 a search cursor is started to read for each record the RegID_6k99 and the FLABEL (please note the I'm using flds.index(fieldname) to determine the index number to access the correct field in the row tuple) on line 26, there is a test to see if the FLABEL value actually exists as fieldname in the fc on line 27, the value is read for the FLABEL value field lines 28 - 31 add the value to the result dictionary. The dictionary will contain each RegID_6k99 value and the sum of the values on line 38 a update cursor is defined which will update the RegIntFlows value of the cursor assuming the field RegIntFlows already exists I hope this makes sense to you and that the code actually runs. If not, please let me know and I see what I can do. Kind regards, Xander
... View more
07-27-2014
05:59 PM
|
2
|
4
|
4525
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 01-09-2020 09:26 AM | |
| 6 | 12-20-2019 08:41 AM | |
| 1 | 01-21-2020 07:21 AM | |
| 2 | 01-30-2020 12:46 PM | |
| 1 | 05-30-2019 08:24 AM |
| Online Status |
Offline
|
| Date Last Visited |
yesterday
|