3

I have a table with two elements in this format:
a b
b a
b c
c b
c d
....
f g
g f

I have to analize if the second element is equal to the first element of the following row. If it's true, 1 is set in a new field. If not the marker is added by 1 +1. This is my code so far:

with arcpy.da.SearchCursor(tab_selektiert, ["field1"],) as n1_cur:
    with arcpy.da.UpdateCursor(tab_selektiert, ["field2", "markerfield"]) as n_cur:
        filler_row = next(n1_cur)
        for n_row, n1_row in izip_longest(n_cur, n1_cur, fillvalue=filler_row):
            if n1_row[0] == n_row[0]:
n_row1 = counter n_cur.updateRow(n_row) else: numcounter = + 1 n_row1 = counter n_cur.updateRow(n_row)

del n_cur
del n1_cur

My problem is that beside the search cursor the n_cursor also skip one line. As result I only get b=b, c=c and missing a=b [..]

Edit
My results should be something like this:
enter image description here
the field_2[0] and field_1[0](next row value) or field_1[0] and field_2[0](next row value) have to be equal (blue arrows).
If so a marker (started with 1) has to set in the markerfield. In the picuture from line 6 to 7, the continuity makes a step forward and the marker has to update by 1 in line 7. Line 6 has '1' as marker even while the continuity breaks, because 'c' is in linie before.


Edit 2
counter = 1
numberlist = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]

with arcpy.da.UpdateCursor(tab_selektiert, (ufield1, ufield2)) as u_cur: with arcpy.da.SearchCursor(tab_selektiert, sfield1) as s_cur: next(s_cur) for sfield1, in s_cur: ufield1, ufield2 = next(u_cur)

print("field 1 " + sfield1 + "---" + " field 2 " + ufield1) print("field 2 + 1 " + str(int(ufield1[-1:]) + int(1))) print("fiel 1 " + str(sfield1[-1:])) print("---") if sfield1 == ufield1: ufield2 = counter elif sfield1[-1] in numberlist and ufield1[-1] in numberlist: if int(ufield1[-1:]) + int(1) == int(sfield1[-1]): ufield2 = counter elif ufield1[-1] == "9" and sfield1[-1] == "0": ufield2 = counter else: counter+=1 ufield2 = counter u_cur.updateRow((ufield1, ufield2))


This gets me to the Point that all fields with a continuity get the marker 1. But a break in the continuity like 'd' to 'f' don't activate the else clause. This fields are just empty, also the last row and the following rows still gets the 1 as marker.

  • Could you edit your question and add the desired output field values to your table example? – BERA Jan 22 at 20:18
  • 2
    I would use list comprehension and a search cursor first so that you can look up the next row's values as you run your second cursor to update values. – PolyGeo Jan 22 at 20:22
  • Could you please edit your question to include an example of your desired output? – Aaron Jan 23 at 6:44
  • 1
    I'm sorry for the confusion. I hope the picture is much better than my "explaining". thank you for trying to help me – Seb Jan 23 at 8:53
3

Like @PolyGeo said, list comprehensions will help. I notice, too, that you don't define counter in your code block. Without understanding what it is, I've included it as I think you meant to have it.

    field1_list = [row[0] for row in arcpy.da.SearchCursor(tab_selektiert, ["field1"])]
    field2_list = [row[0] for row in arcpy.da.SearchCursor(tab_selektiert, ["field2"])]

    #Assuming here that counter must initialize at 1. If if should initialize at 0,
    # just change it.
    counter = 1 
    index = 0

    with arcpy.da.UpdateCursor(tab_selektiert, ["markerfield"]) as updater:
        for row in updater:
            #The value of index should never exceed len-2, since len is always
            # 1 more than the highest index value, and your function will only
            # check up to the next-to-last item in the list (the last item has
            # nothing to compare to
            if index<=len(field1_list)-2:
                n0 = field1_list[index] #The field1 value for current index
                n1 = field2_list[index] #The field2 value for the current index
                n2 = field1_list[index+1] #The field1 value for the next index
                n3 = field2_list[index+1] #The field2 value for the next index

                if n1==n2 or n3==n0 or n0==n2:
                    #EDIT: Index only increases if none of the numbers
                    # match. The markerfield is always updated with
                    # counter. 
                else:
                    #This is the condition where counter is increased
                    counter+=1

                updater.updaterRow([counter])
                index+=1

            else:
                #If you've reached the last item, update the last row with counter,
                # then break out of the loop
                updater.updateRow([counter])
                break

It's worth noting that you said counter= +1, but in python the way to do what you're trying to do is as I have it: counter+=1. I hope this helps!

  • Thank you. This works fine, but if there is a break in the continuity the markerfield doesn't raise up. I tested also a to check the values crosswise with if n==n1 or n3==2 with the same result. Only got '1' in the markerfield – Seb Jan 23 at 8:21
  • Hey @Seb, I updated the conditional in the middle to reflect what you have in the image above. However, your comment makes it sound like you want the markerfield to increase with continuity and reset when continuity breaks. Is the image you added how you want it to be? – flintlockspecial Jan 23 at 14:26
  • Hi :-), every following row with the same continuity should get the same value, starting with '1'. Mean like a >b, b > c, c >d have '1' d > f, f > g have '2' I'm sorry it's confusing I know – Seb Jan 23 at 15:24
  • Okay, awesome! My edit should output exactly that! (what you have in the image). Let me know if something's still wrong! – flintlockspecial Jan 23 at 15:34
  • I needed the update.Row() comment under the If clause but thank you very much ! Works great ! – Seb Jan 24 at 13:22
2

Iterate your table and assign your value and the oid to variables. Create a set of OIDs with values equal to the next value by comparing the last oid to the current. Iterate one more time and update the field by checking OIDs.

oids = set ()

#perform check
with arcpy.da.SearchCursor(tab_selektiert, ["field1", "field2", "OID@"]) as curs:
    for fld1, fld2, oid in curs:
        try: lastVal
        except NameError:
            lastVal = fld2
            lastOid = oid
            continue
        if fld1 == lastVal:
            oids.add (lastOid)
        lastVal = fld2
        lastOid = oid


#update
counter = 0
with arcpy.da.UpdateCursor(tab_selektiert, ["OID@", "markerfield"]) as curs:
    for oid, mark in curs:
        if not oid in oids:
            counter += 1
        row = (oid, counter)
        curs.updateRow (row)
1

This is another way you can do it:

import arcpy
fc = r'C:\Default.gdb\adress1'
field_to_read = 'Textfield'
field_to_update = 'Integerfield'

all_letters = ''.join([i[0] for i in arcpy.da.SearchCursor(fc,field_to_read)]).replace(' ','') #Create one long string, 'abbabccbcd'
cursor = arcpy.da.UpdateCursor(fc,field_to_update)
count = 1
for pair,row in zip(zip(all_letters[1::2],all_letters[2::2]),cursor): #Iterate over pairs of letters (last letter, first letter) -> (b,b), (a,b), (c,c) etc. and the cursor
    if len(set(pair))==1: #If the letters are the same, length of set will be 1
        row[0] = count
        cursor.updateRow(row)
    else:
        count+=1
del cursor

enter image description here

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.