Select to view content in your preferred language

Arcpy rejecting outputs of recursive math expressions/python methods

636
1
07-11-2019 05:34 AM
wwnde
by
Regular Contributor

9/10 spatial analysis I do involve mathematical expressions. Users want me to execute recursive math functions,to aid spatial analysis and clustering. I have challenges passing such expressions into arcpy.da and Code Blocks in calculate field. A simple case in point;

I have the table below. I need the code to recursively calculate minimum start date and find the Date range between this date and finishdate. If the range is <=60, the Cat should increment by 1 else it should remain as -1. The challenge is, ternary operator in the def function refuses to update because my method does not assign item at line 62. 

OBJECTID_1 *Conc *IDstartfinishDateRangeCat
1ASPELBJNMILAPMT6/27/20188/11/2018100-1
2ASPELBJNMIKLKIY8/22/20188/31/2018100-1
3ASPELBJNMIHDOKK8/12/20189/30/2018100-1
4ASPELBJNMIXMCZW8/22/201810/20/2018100-1
5BKRKAVQTZCFCBES7/1/20188/15/2018100-1
6BKRKAVQTZCNHQGW8/24/20189/4/2018100-1
7BKRKAVQTZCLVUSS8/9/201810/4/2018100-1
8BKRKAVQTZCRQVNN8/18/201810/24/2018100-1
9FKKTHEJGCYIHORM7/2/20188/20/2018100-1
10FKKTHEJGCYAZFEV8/28/20189/8/2018100-1
11FKKTHEJGCYYAVOY8/4/20189/29/2018100-1
12FKKTHEJGCYAMWAX8/16/201810/22/2018100-1
13JUNRNEXCRGQCOWV6/30/20188/25/2018100-1
14JUNRNEXCRGAOYNL8/25/20189/9/2018100-1
15JUNRNEXCRGCGCHK8/4/201810/3/2018100-1
16JUNRNEXCRGIQYGJ8/12/201810/26/2018100-1
import arcpy
from datetime import datetime
from datetime import datetime as dt
from datetime import timedelta
import time
from datetime import date
#Variables Start
arcpy.env.workspace = r'E:\Patch\New File Geodatabase.gdb'
fc= 'patchjoin212'
field =['Conc','ID']
fields = ['start', 'finish', 'DateRange', 'Cat']
Classifyjoin = "Classifyjoin"
Classifyjoin__2_ = Classifyjoin

#Def function

def min_cat(b=datetime.now() , m=datetime.now(), x = 2, y =-1):
    """This function calculates the date range between earliest start in a category to the exact finish date of an individual member"""""
    #return(b-m).days
    e = (b-m).days
    f = ( x if e<=60 else y)
    return {'e': e, 'f':f}
#print ['e']
#print ['f

#print min_cat(b=dt.strptime('2019-06-26', '%Y-%m-%d').date(),  m=dt.strptime('2018-11-29', '%Y-%m-%d').date(), x= 9, y=-1)


#temp_lyr = arcpy.MakeFeatureLayer_management(fc, "temp_lyr") #If using a fc in gdb
temp_lyr= arcpy.MakeTableView_management(fc, "temp_lyr")


#Variables end


ud = {}

with arcpy.da.SearchCursor(fc, field) as rows:
    for row in rows:
        if row[0] not in ud:
            ud[row[0]] = row[1]
          
for k in ud:

            
    
    where_clause="Conc IN( '%s')" % k #+ "AND ID IN( '%s')" %v
    #print(where_clause)
    kala = arcpy.SelectLayerByAttribute_management(temp_lyr, 'NEW_SELECTION', where_clause)#Carry out the selection
    cnt = arcpy.GetCount_management(temp_lyr) # Counting the selected and copied features
    print("The number of selected records is: " + str(cnt))
    
    
   
    listdates = []
    listCat =[]
    bv =[]
    #k = [row[3] for row in arcpy.da.SearchCursor(fc, ["start", "finish", "DateRange", "Cat"]) if row [2]<60]
    with arcpy.da.UpdateCursor(fc, fields) as cursor:
            
        for row in cursor:
            listCat.append(row[3])
            jp =min(listCat)
            kp = int('{}'.format(jp))
            kp +=1
                #while row[3]==0:
            if row[3]==-1:
                listdates.append(row[0])

                pg =min(listdates)#.date()
                jup = '{}'.format(pg)
                jop = dt.strptime(jup, '%Y-%m-%d %H:%M:%S').date()
                
                bg = '{}'.format(row[1])
                job = dt.strptime(bg, '%Y-%m-%d %H:%M:%S').date()
                a =min_cat(b= job, m=jop, x= kp, y=-1)
                row[2] = a['e']
                cursor.updateRow(row)
                #u = categories(k)
                rows[3] = a['f']
                cursor.updateRow(rows)
                
    del cursor, row    


     
print ("finished")
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

How can I best call recursive spatial stat approaches of mathematical nature encapsulated in ternary operators, comprehensions etc into arcpy or arcpy.da.? Any way out? Any other approach? Or is this outside the spatial stat world?

Also posted https://stackoverflow.com/questions/56945606/passing-a-ternary-operator-recursively-returns-method-d...

0 Kudos
1 Reply
wwnde
by
Regular Contributor

Code ok. Typo ;

rows

  at line 80 and 81 noted and rectified. It was meant to be row. corrected code below:

import arcpy
from datetime import datetime
from datetime import datetime as dt
from datetime import timedelta
import time
from datetime import date
#Variables Start
arcpy.env.workspace = r'E:\Patch\New File Geodatabase.gdb'
fc= 'patchjoin212'
field =['Conc','ID']
fields = ['start', 'finish', 'DateRange', 'Cat']
Classifyjoin = "Classifyjoin"
Classifyjoin__2_ = Classifyjoin
def min_cat(b=datetime.now() , m=datetime.now(), x = 2, y=-1):
    """This function calculates the date range between earliest start in a category to the exact finish date of an individual member"""""
    #return(b-m).days
    lg =[2]
    e = (b-m).days
    f = {True: x, False: y} [e <= 60]#(y, x) [e <=60 ] # [ x if e<=60 else -1]
    return [ e, f]
#cb = min_cat(b=dt.strptime('2019-06-26', '%Y-%m-%d').date(),  m=dt.strptime('2018-11-29', '%Y-%m-%d').date(), x= [9])
print min_cat(b=dt.strptime('2019-06-26', '%Y-%m-%d').date(),  m=dt.strptime('2018-11-29', '%Y-%m-%d').date(), x= [9], y=[-1])
temp_lyr= arcpy.MakeTableView_management(fc, "temp_lyr")
ud = {}
with arcpy.da.SearchCursor(fc, field) as rows:
    for row in rows:
        if row[0] not in ud:
            ud[row[0]] = row[1]          
for k in ud:
    where_clause="Conc IN( '%s')" % k #+ "AND ID IN( '%s')" %v
    #print(where_clause)
    kala = arcpy.SelectLayerByAttribute_management(temp_lyr, 'NEW_SELECTION', where_clause)#Carry out the selection
    cnt = arcpy.GetCount_management(temp_lyr) # Counting the selected and copied features
    print("The number of selected records is: " + str(cnt))
    listdates = []
    listCat =[]
    
    with arcpy.da.UpdateCursor(fc, fields) as cursor:
            
        for row in cursor:
            listCat.append(row[3])
            jp =max(listCat)
            kp = int('{}'.format(jp))
            kp +=1
            if row[3]==-1:
                listdates.append(row[0])

                pg =min(listdates)#.date()
                jup = '{}'.format(pg)
                jop = dt.strptime(jup, '%Y-%m-%d %H:%M:%S').date()
                
                bg = '{}'.format(row[1])
                job = dt.strptime(bg, '%Y-%m-%d %H:%M:%S').date()
                a =min_cat(b= job, m=jop, x= kp, y=-1)
                row[2] = a[0]
                cursor.updateRow(row)
                #u = categories(k)
                row[3] = a[1]
                cursor.updateRow(row)
               
    del cursor, row     
print ("finished")

Thanks

0 Kudos