Select to view content in your preferred language

Concatenate Multi-Values from Single Field and Insert to Single Cell

4582
22
01-28-2021 02:28 PM
EricMahaffey1
Frequent Contributor

I'm building a geoprocessing model that iterates through features in one f-class and spatially selects features from another f-class that are within a certain distance of each feature.  I want to pull values from one f-class to the other.  The model essentially does a select features by location, and from that selection I would like to pull values within a single field, concatenate them together as a string and insert that value into the other f-class field in a single cell. I believe that I need to use some cursors within ArcPy to do this (SearchCursor & InsertCursor) and embed the Python script within the model, but I'm not entirely sure. So basically Table1 FIELD_A has two values "1234" and "5678". I want to take those two values and insert them into a single cell within Table2 FIELD_B so that the value looks something like "Value 1: 1234 to Value 2: 5678". Any assistance would be appreciated.

0 Kudos
22 Replies
EricMahaffey1
Frequent Contributor

Jeff,

I've now realized that I needed to switch out the InsertSursor with UpdateCursor because I'm trying to put the values into an existing feature's MILE_MARKERS value.  Using your last code sample I made that change along with some other minor tweaks, and got the correct value to populate the cell "Value 1: 336 Value 2: 337".  I had to switch from using the OBJECTID field to a MILE integer field in the table in order to capture the values in ascending order.  This is so that the value shows a range in mile markers.  So the code runs, but then throws an error:

"previousMT = [x[1] for x in arcpy.da.SearchCursor(Adjacent_MileMarkers, ['MILE', 'MILE_TEXT'], wc)][0]
IndexError: list index out of range"

with arcpy.da.SearchCursor(Adjacent_MileMarkers, ['MILE', 'MILE_TEXT']) as S_cursor:
    for row in S_cursor:
        # Use your lowest ID here because that will be your floor
        if row[0] != 1:
            # Create your filter to get the previous value using the current Id - 1
            wc = """MILE = {}""".format(row[0] - 1)
            #wc = """OBJECTID = {}""".format(row[0] - 1)
            # get the previous Mile_Text value by filtering the for Id -1
            previousMT = [x[1] for x in arcpy.da.SearchCursor(Adjacent_MileMarkers, ['MILE', 'MILE_TEXT'], wc)][0]
            resString = 'Value 1: {} Value 2: {}'.format(previousMT, row[1])
            print "Initial resString is: " + (resString)
        else:
            # if the incoming selection is your floor, there will not be any previous 'MILE_TEXT'.
            resString = 'Value 1: {}'.format(row[1])
            print "else resString is: " + (resString)
        # update target FC
        with arcpy.da.UpdateCursor(River_Section, 'MILE_MARKERS') as U_cursor:
            for row in U_cursor:
                U_cursor.updateRow([resString])

I think I need to end it after one pass somehow.

0 Kudos
by Anonymous User
Not applicable

The best thing to do here is use the **bleep** and see what your variables values are.  There is two indexes in that statement.  x[1] referring to the value in the 'MILE_TEXT' field, and the List index at the end [0].  If there is nothing returned by that cursor, the x[1] will throw the index out of range.  If there is nothing from the list comprehension, then the [0] will throw the index out of range.  Hard to say which one is failing.

However, if you are going by the -1, mile why not just subtract one from the current mile, and skip the searchcursor that is getting the current mile - 1?  would that give you what you want?  [I added that part incase the miles were not sequential and you needed to go by the sequence of the row Id's.]

 

0 Kudos
EricMahaffey1
Frequent Contributor

I finally figured it out, and sharing the code in case anyone runs into a similar situation and needs some sample code to get them started

import arcpy

# Local variables:
River_Section = "C:\<path to your GDB f-class>"
Adjacent_MileMarkers = "C:\<path to your GDB f-class>"

scursor = [row[0] for row in arcpy.da.SearchCursor(Adjacent_MileMarkers, ("MILE_TEXT"))]
print "List Comprehension value is: " + str(scursor)

i=0
ucursor = arcpy.da.UpdateCursor(River_Section, ["MILE_MARKERS"])

for row in ucursor:      
    row[0] = str('Mile Marker:' + scursor[i] + ' to Mile Marker:' + scursor[i+1])
    print row[0]
    ucursor.updateRow(row)

print "Script Complete"