[GIS] Calculating field based on content from another table with no join in ModelBuilder

arcgis-10.3arcgis-desktoparcpymodelbuilderpython-parser

I'm trying to work out how if (at all) it is possible to do a field calculation where there is no join or relationship between two attribute tables in ArcGIS 10.3.1. I've searched all over the place for a solution.

In my example, my model already selects some features based on an attribute, resulting in a featureclass with approximately 2000 features, with population figures assigned to them. I already have a table with the significant loadings that each of the population figures has towards a final score.

I basically want to be able to do the following calculation.

[Featureclass Field Value]*[Table Field Significant loading]

I'm trying to avoid "hard coding" the significant loadings into the field calculation so that I can just update the table, rather than having to change several parts of the model, when/where necessary.

I can't join or relate the tables within ArcMap as they have no common field.

I suspect that this might be able to be done with Python but it's been a while since I used it and I'm getting errors every time I try so I think I may be missing something fundamental, not seeing the wood for the trees.

My first attempt is this but IDLE gives me an errors after I define the parameters (ie: when I tell it I want it to multiply stuff)

import arcpy
import os

# Defined within model
SLO65Sing = arcpy.GetParameterAsText(0) #Significant Loading field 1
SLO65All = arcpy.GetParameterAsText(0) #Significant Loading field 2
ValO65Sing = arcpy.GetParameterAsText(0) #Value field 1 
ValO65All = arcpy.GetParameterAsText(0) #Value field 2 
FSO65Sing = arcpy.GetParameterAsText(0) #Factor Score field 1
FSO65All = arcpy.GetParameterAsText(0) #Factor Score field 2

def Calc_O65Sing(SLO65Sing*ValO65Sing)

Calc_O65Sing(!FSO65Sing!)

def Calc_O65All(SLO65All*ValO65All)

Calc_O65All(!FSO65All!)

Note: moved this over from Stackoverflow when I realised I had posted it in the wrong place!

Best Answer

I do believe I pulled together what now seems like quite a simple solution. I've used da.SearchCursor and da.UpdateCursor and been able to use GetParameterAsText. As my significant loadings for my factor scores are only in one row of my table I was able to tell arcpy to just look at that row. The code is below:

#Factor score calculation for population values and significant loading
#Date: January 2017
#Purpose: to be incorporated into ArcGIS models so that the user can calculate factor scores for energy sustainability.
#Further information: will only work if significant loading table has one line


import arcpy
from arcpy import env

env.workspace = arcpy.GetParameterAsText(0) #Define working environment (geodatabase)
fc = arcpy.GetParameterAsText(1) #Feature class with population values
tbl = arcpy.GetParameterAsText(3) #Table with significant loadings
valfield = arcpy.GetParameterAsText(2) #Field in fc that has population values
slfield = arcpy.GetParameterAsText(4) #Field in tbl with relevant significant loading value
factfield = arcpy.GetParameterAsText(5) #Field which will be populated with factor score

slcursor = arcpy.da.SearchCursor(tbl,slfield)
for row in slcursor:
    sigload = row[0]

with arcpy.da.UpdateCursor(fc,[valfield, factfield]) as ucursor:
    for row in ucursor:
        row[1]=row[0]*sigload
        ucursor.updateRow(row)
        print (row)

del row
del ucursor

It seems to work fine (I've checked the maths), I just need to incorporate it into my model now - I've written it here in such a way that I should be able to re-use this script across other parts of the model where I need to calculate other significant loadings as well.