Python Rolling Average for Road Sections

83
1
Wednesday
DanH7
by
New Contributor

Hi All,

I have a road network dataset with 100m sections with a condition score and need an rolling average of the score for the previous 10 segments. This is for road maintenance planning & prioritisation.

I would like an efficient way to do this in python (to be incorporated into model builder). In a geoprocessing model I have achieved an average using a iterative selected distance and summary stats but it takes a very long time (over a month) to process the +100K sections. I have been shown it can be done in seconds in excel. To incorporate the process into an automated workflow, python is the go but I lack the experience.

The data example I have attached consists of:

  • Road section - Road ID (RID) which identifies the road,
  • Tdist  start and end - Through distance / chainage, each section is identified by a start and end,
  • C Score - Condition score.

I have access to the numpy library also. Hopefully some data science guru can help me.

I appreciate any help and thanks in advance 🙂

Example sectionsExample sections

0 Kudos
1 Reply
DanPatterson
MVP Honored Contributor

Projected data only.

Skip the shapefile, use a local gdb featureclass.

Running mean/rolling average    same

arcpy.da.ExtendTable to join an array back to a featureclass table

Lesson to emulate, example 20 numbers with a rolling 5 average, hence the first 2 and last 2 will be nodata (nan = not a number)

import numpy as np
from numpy.lib.stride_tricks import sliding_window_view as swv
# create an empty array with 20 rows and 3 columns (int, float, float)
z = np.empty(shape=(20,), dtype=[("ids", 'i8'), ("vals", "f8"), ("rolling_mean", "f8")])
z["ids"] = np.arange(20)
z["vals"] = np.random.randint(0, 10, 20) * 1.0
z["rolling_mean"] = np.repeat(np.nan, 20)
rolling_win = swv(z["vals"], 5)
means_ = np.mean(rolling_win, axis=1)
z["rolling_mean"][2:18] = means_  # do the slicey thing since there are 16 vals
z
array([( 0, 1., nan), ( 1, 7., nan), ( 2, 7., 5.4), ( 3, 8., 5.2),
       ( 4, 4., 4. ), ( 5, 0., 2.6), ( 6, 1., 1.4), ( 7, 0., 1.4),
       ( 8, 2., 2.8), ( 9, 4., 3.2), (10, 7., 4. ), (11, 3., 4.2),
       (12, 4., 4. ), (13, 3., 3. ), (14, 3., 2.6), (15, 2., 2. ),
       (16, 1., 1.6), (17, 1., 1.4), (18, 1., nan), (19, 2., nan)],
      dtype=[('ids', '<i8'), ('vals', '<f8'), ('rolling_mean', '<f8')])

 


... sort of retired...