Skip to main content
edited to run as stand alone script, rather than within modelbuilder
Source Link
import math
import arcpy
fc= "e:/NCCA/Temp/Temp.gdb/table_three"near_table"
bearings = ["IN_FID", "bearing", "bearing_avg"]
def calc():
    #creates a dictionary with the IN_FID as the key, and the bearing as the values
    valueDict = {}
    with arcpy.da.SearchCursor(fc, bearings) as searchRows:  
        for searchRow in searchRows:  
            keyValue = searchRow[0]  
            if not keyValue in valueDict:
                valueDict[keyValue] = [searchRow[1]] 
            else:  
                valueDict[keyValue].append(searchRow[1]) 
    
    #calculates the bearing average of the values for each dictionary key and puts the average bearing into a new dictionary
    averageBearingDict = {}
    for key in valueDict:
        cosSum = 0.0
        sinSum = 0.0
        for bearingVal in valueDict[key]:
            theCos = math.cos(math.radians(float(bearingVal)))  
            theSin = math.sin(math.radians(float(bearingVal)))  
            cosSum += theCos  
            sinSum += theSin  
        N = len(valueDict[key]) 
        C = cosSum/N  
        S = sinSum/N  
        theMean = math.atan2(S,C)  
        if theMean < 0.0:  
            theMean += math.radians(360.0)  
        theMean_deg = math.degrees(theMean)

        averageBearingDict[key] = theMean_deg

    #this puts the calculated bearing average back into the table - in row "bearing_avg"
    with arcpy.da.UpdateCursor(fc, bearings) as rows:
        for row in rows:
            row[2] = averageBearingDict[row[0]]
            rows.updateRow(row)

This runs within the code block of the calculate field tool, within modelbuilder, with the expression set to calc()has been run as a stand alone script and completes in less than a minute.

import math
fc= "e:/NCCA/Temp/Temp.gdb/table_three"
bearings = ["IN_FID", "bearing", "bearing_avg"]
def calc():
    #creates a dictionary with the IN_FID as the key, and the bearing as the values
    valueDict = {}
    with arcpy.da.SearchCursor(fc, bearings) as searchRows:  
        for searchRow in searchRows:  
            keyValue = searchRow[0]  
            if not keyValue in valueDict:
                valueDict[keyValue] = [searchRow[1]] 
            else:  
                valueDict[keyValue].append(searchRow[1]) 
    
    #calculates the bearing average of the values for each dictionary key and puts the average bearing into a new dictionary
    averageBearingDict = {}
    for key in valueDict:
        cosSum = 0.0
        sinSum = 0.0
        for bearingVal in valueDict[key]:
            theCos = math.cos(math.radians(float(bearingVal)))  
            theSin = math.sin(math.radians(float(bearingVal)))  
            cosSum += theCos  
            sinSum += theSin  
        N = len(valueDict[key]) 
        C = cosSum/N  
        S = sinSum/N  
        theMean = math.atan2(S,C)  
        if theMean < 0.0:  
            theMean += math.radians(360.0)  
        theMean_deg = math.degrees(theMean)

        averageBearingDict[key] = theMean_deg

    #this puts the calculated bearing average back into the table - in row "bearing_avg"
    with arcpy.da.UpdateCursor(fc, bearings) as rows:
        for row in rows:
            row[2] = averageBearingDict[row[0]]
            rows.updateRow(row)

This runs within the code block of the calculate field tool, within modelbuilder, with the expression set to calc().

import math
import arcpy
fc= "e:/NCCA/Temp/Temp.gdb/near_table"
bearings = ["IN_FID", "bearing", "bearing_avg"]
#creates a dictionary with the IN_FID as the key, and the bearing as the values
valueDict = {}
with arcpy.da.SearchCursor(fc, bearings) as searchRows:  
    for searchRow in searchRows:  
        keyValue = searchRow[0]  
        if not keyValue in valueDict:
            valueDict[keyValue] = [searchRow[1]] 
        else:  
            valueDict[keyValue].append(searchRow[1]) 

#calculates the bearing average of the values for each dictionary key and puts the average bearing into a new dictionary
averageBearingDict = {}
for key in valueDict:
    cosSum = 0.0
    sinSum = 0.0
    for bearingVal in valueDict[key]:
        theCos = math.cos(math.radians(float(bearingVal)))  
        theSin = math.sin(math.radians(float(bearingVal)))  
        cosSum += theCos  
        sinSum += theSin  
    N = len(valueDict[key]) 
    C = cosSum/N  
    S = sinSum/N  
    theMean = math.atan2(S,C)  
    if theMean < 0.0:  
        theMean += math.radians(360.0)  
    theMean_deg = math.degrees(theMean)

    averageBearingDict[key] = theMean_deg

#this puts the calculated bearing average back into the table - in row "bearing_avg"
with arcpy.da.UpdateCursor(fc, bearings) as rows:
    for row in rows:
        row[2] = averageBearingDict[row[0]]
        rows.updateRow(row)

This has been run as a stand alone script and completes in less than a minute.

Source Link

Using the post of Richard Fairhurt and this post for the bearing average I came up with the following solution:

import math
fc= "e:/NCCA/Temp/Temp.gdb/table_three"
bearings = ["IN_FID", "bearing", "bearing_avg"]
def calc():
    #creates a dictionary with the IN_FID as the key, and the bearing as the values
    valueDict = {}
    with arcpy.da.SearchCursor(fc, bearings) as searchRows:  
        for searchRow in searchRows:  
            keyValue = searchRow[0]  
            if not keyValue in valueDict:
                valueDict[keyValue] = [searchRow[1]] 
            else:  
                valueDict[keyValue].append(searchRow[1]) 
    
    #calculates the bearing average of the values for each dictionary key and puts the average bearing into a new dictionary
    averageBearingDict = {}
    for key in valueDict:
        cosSum = 0.0
        sinSum = 0.0
        for bearingVal in valueDict[key]:
            theCos = math.cos(math.radians(float(bearingVal)))  
            theSin = math.sin(math.radians(float(bearingVal)))  
            cosSum += theCos  
            sinSum += theSin  
        N = len(valueDict[key]) 
        C = cosSum/N  
        S = sinSum/N  
        theMean = math.atan2(S,C)  
        if theMean < 0.0:  
            theMean += math.radians(360.0)  
        theMean_deg = math.degrees(theMean)

        averageBearingDict[key] = theMean_deg

    #this puts the calculated bearing average back into the table - in row "bearing_avg"
    with arcpy.da.UpdateCursor(fc, bearings) as rows:
        for row in rows:
            row[2] = averageBearingDict[row[0]]
            rows.updateRow(row)

This runs within the code block of the calculate field tool, within modelbuilder, with the expression set to calc().