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 * ID start finish DateRange Cat 1 ASPELBJNMI LAPMT 6/27/2018 8/11/2018 100 -1 2 ASPELBJNMI KLKIY 8/22/2018 8/31/2018 100 -1 3 ASPELBJNMI HDOKK 8/12/2018 9/30/2018 100 -1 4 ASPELBJNMI XMCZW 8/22/2018 10/20/2018 100 -1 5 BKRKAVQTZC FCBES 7/1/2018 8/15/2018 100 -1 6 BKRKAVQTZC NHQGW 8/24/2018 9/4/2018 100 -1 7 BKRKAVQTZC LVUSS 8/9/2018 10/4/2018 100 -1 8 BKRKAVQTZC RQVNN 8/18/2018 10/24/2018 100 -1 9 FKKTHEJGCY IHORM 7/2/2018 8/20/2018 100 -1 10 FKKTHEJGCY AZFEV 8/28/2018 9/8/2018 100 -1 11 FKKTHEJGCY YAVOY 8/4/2018 9/29/2018 100 -1 12 FKKTHEJGCY AMWAX 8/16/2018 10/22/2018 100 -1 13 JUNRNEXCRG QCOWV 6/30/2018 8/25/2018 100 -1 14 JUNRNEXCRG AOYNL 8/25/2018 9/9/2018 100 -1 15 JUNRNEXCRG CGCHK 8/4/2018 10/3/2018 100 -1 16 JUNRNEXCRG IQYGJ 8/12/2018 10/26/2018 100 -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...
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