0

I see lots of examples of updating a specific column down ALL rows of a table, for example:

with arcpy.da.UpdateCursor(Input_Layer, ['Column_1','Column_2']) as cursor:
    for row in cursor:
         row.setValue('Column_1', value1)
         row.setValue('Column_2', value2)

...but how do you update a specific field in JUST ONE row (specifically the bottom, currently blank row)?

Selecting specific row in attribute table using ArcPy (without iterating through whole table)? explains how to point to a specific row that already exists, but in my case the row/column I want to update is currently blank and has no other columns I can use to specify it.

My code will begin a loop, gather 3 numerical values (based on calculations from other columns in the table), and then store those 3 values in 3 (initially) blank "tally columns", but again, only in the first row .

The next time through the loop the three "tally columns" would be updated with the newly calculated values, but now only in row 2.

And then row 3, etc...

The following image shows my original table (green columns) plus the summary statistics that I wish to add (orange columns) by iterating through multiple uses of SelectLayerByAttribute_management and then UpdateCursor.

enter image description here

The image tries to capture a point during my repeated looping where SelectLayerByAttribute_management is fed the following values...

value1 = "01"
value2 = "030"
value3 = "003"

...for the following query.

query = '"{0}" = {1} AND "{2}" = {3} AND "{4}" = {5}'.format(column1, value1, column2, value2, column3, value3)

...and then updates the 3 "tally columns" in just the highlighted row you see in the orange section (which at that time is the newest row at the bottom).

Here's the Key: Each time through the code will update the "tally columns" in only the bottom row (which is initially blank) .

How can I refer to that bottom, initially blank row? Using an index? For example, if I employed a counter variable, x, starting at 0 and then increased it by one (x+=1) each time through the loop, something like this would work?

with arcpy.da.UpdateCursor(Input_Layer, ['locator','area','sum']) as cursor:
    row[x].setValue('locator', value1)
    row[x].setValue('area', value2)
    row[x].setValue('sum', value2)

Or perhaps a Where Clause will be useful? But in that case I would be interested in "the next row that is currently blank" and I don't know how to code that statement.

  • 1
    Your code snippet seems to be mixing syntax from old and new style cursors. In any event the way to update the last row using an UpdateCursor will be to GetCount how many rows there are and then when you open the cursor use a where_clause to restrict it to just the last row. – PolyGeo Jun 15 '18 at 0:20
  • Thanks, I know how to construct a where_clause to find a row with a specific value in a specific field, but how do I refer to a row that does not yet have anything in it? – Waterman Jun 15 '18 at 0:29
  • A row "that does not yet have anything in it" sounds like a row where all fields have no values so just construct a where_clause for that. Is there any chance that what you actually want to do is to use an InsertCursor? – PolyGeo Jun 15 '18 at 0:37
  • No, the other rows have values in them... hundreds in fact. I'm starting two new rows to gather summary statistics in them, area and count sums to be exact. So all I want to do is store these statistics somewhere. I thought the simplest would be to store them in the same table they came from. Perhaps it would simpler to have my code store them in a brand new empty table? I've never referred to a 'secondary' table in any of my scripts before though so I'm not sure how I'd do that. – Waterman Jun 15 '18 at 0:54
  • It sounds like your question may need an overhaul that starts with a picture of a simplified version of the table you want to start with and how you want it to look afterwards. – PolyGeo Jun 15 '18 at 0:57
2

In your picture your orange "table" looks like it could be easily derived from your green "table" using the Summary Statistics tool with square_km SUM as your statistics field and three case fields (column1, column2 and column3).

  • Thanks, this was the solution to what I was really trying to do. The fact there was a tool to compute what I needed rendered my original question a moot point. In the interests of this site I'm inclined to drastically edit the original question so that it matches your eventual solution. Would you agree? – Waterman Jun 27 '18 at 21:42
  • Retrofitting a question to its existing answers is something that I think is fine to do. However, I think that when doing so much care must be taken not to invalidate any existing answers, especially if they have been upvoted. If it cannot be retrofitted so as not to strand either of the current answers on this question, then I think it would be best to leave the question as-is and aim to next time write a question like you wish you had written for this one. – PolyGeo Jun 27 '18 at 22:15
  • A fair comment about "stranding" other answers but as for aiming in future to write questions the way it turns out they should be written, well... that's a bit of "horse before the cart", since I had no idea the Summary Statistics Tool existed and was asking a question to solve one step on my attempt to scripting my own "summary statistics". Your answer saved me from that needless work and was the simplest path to my "overall destination, but strictly speaking the real answer to my original question was given by FelixIP. – Waterman Jun 27 '18 at 22:31
  • Asking focused questions is a skill that I think takes many years to master. The immense value of questions that can be instantly recognized by visitors encountering the same problem is why we spend so much time during comments to try and hone that skill in all our posters. I actually think my first comment provides a simpler answer to your original question than that of FelixIP, and I think a performance timing between the two approaches would be interesting. – PolyGeo Jun 27 '18 at 22:47
1

There are multiple ways to achieve this through OID field. I think the workflow below is the fastest. I hope it is self-explanatory:

import arcpy
inFC=r'c:\scratch\chps.shp'
inFC=r'C:\SCRATCH\SCRATCH.gdb\eps'
d=arcpy.Describe(inFC)
fidName = d.OIDFieldName
fids=arcpy.da.TableToNumPyArray(inFC,fidName)
lastRecord=fids[-1][0]
fld = arcpy.AddFieldDelimiters(inFC, fidName)
query='%s=%s' %(fld,lastRecord)
with arcpy.da.SearchCursor(inFC,"*",query) as cursor:
    for row in cursor:
        print row

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.