|
| 1 | + |
| 2 | +##### |
| 3 | +# Step 2 - Interpolation and routines to conduct validation |
| 4 | +##### |
| 5 | + |
| 6 | +# We will interpolate a file of elevations, and use a k-fold validation approach, whereby we will loop through creating |
| 7 | +# n interpolations, validate with points that were dropped from the interpolation, and report |
| 8 | +# a correlation value using Pandas. |
| 9 | + |
| 10 | +# This is a multi-step process: |
| 11 | + |
| 12 | +# 1) Let's do a random selection, and save the split files in different directories. |
| 13 | + |
| 14 | +import arcpy |
| 15 | +import random as random |
| 16 | +from arcpy.sa import * |
| 17 | +arcpy.CheckOutExtension("Spatial") |
| 18 | +from scipy.stats.stats import pearsonr |
| 19 | + |
| 20 | +arcpy.env.workspace = r"Z:\Andy's Documents\Teaching and students\URI\NRS - GIS Python Course\Github\Course_ArcGIS_Python\Classes\12_Rasters\Step_2_Data" |
| 21 | +input_data = r"Elevations.shp" |
| 22 | + |
| 23 | +arcpy.env.extent = input_data |
| 24 | + |
| 25 | +kfold = 20 #number of folds |
| 26 | +prop_samples = 30 #proportion of points to split |
| 27 | +i = 0 |
| 28 | + |
| 29 | + |
| 30 | +# Code Obtained from: https://support.esri.com/en/technical-article/000013141, edited to return 2 outputs |
| 31 | +def SelectRandomByPercent (layer, layer2, percent): |
| 32 | + fc = arcpy.Describe(layer).catalogPath |
| 33 | + featureCount = float(arcpy.GetCount_management (fc).getOutput(0)) |
| 34 | + count = int(featureCount * float(percent) / float(100)) |
| 35 | + if not count: |
| 36 | + arcpy.SelectLayerByAttribute_management (layer, "CLEAR_SELECTION") |
| 37 | + return |
| 38 | + oids = [oid for oid, in arcpy.da.SearchCursor(fc, "OID@")] |
| 39 | + oidFldName = arcpy.Describe(layer).OIDFieldName |
| 40 | + delimOidFld = arcpy.AddFieldDelimiters (layer, oidFldName) |
| 41 | + randOids = random.sample (oids, count) |
| 42 | + oidsStr = ", ".join(map(str, randOids)) |
| 43 | + sql = "{0} IN ({1})".format(delimOidFld, oidsStr) |
| 44 | + output1 = arcpy.SelectLayerByAttribute_management(layer, "", sql) |
| 45 | + sql = "{0} NOT IN ({1})".format(delimOidFld, oidsStr) |
| 46 | + output2 = arcpy.SelectLayerByAttribute_management(layer2, "", sql) |
| 47 | + return output1, output2 |
| 48 | + |
| 49 | + |
| 50 | +while i < kfold: |
| 51 | + arcpy.MakeFeatureLayer_management(input_data, "input_data_lyr") |
| 52 | + arcpy.MakeFeatureLayer_management(input_data, "input_data_lyr2") |
| 53 | + output1, output2 = SelectRandomByPercent("input_data_lyr", "input_data_lyr2", prop_samples) |
| 54 | + arcpy.CopyFeatures_management(output1, "elv_" + str(i) + "_test.shp") |
| 55 | + arcpy.CopyFeatures_management(output2, "elv_" + str(i) + "_train.shp") |
| 56 | + arcpy.Delete_management("input_data_lyr") |
| 57 | + arcpy.Delete_management("input_data_lyr2") |
| 58 | + i = i + 1 |
| 59 | + |
| 60 | + |
| 61 | +# 2) Now let's create several surfaces using simple interpolation: |
| 62 | + |
| 63 | +training_shp = arcpy.ListFeatureClasses("*train*") |
| 64 | +count = 0 |
| 65 | + |
| 66 | +for i in training_shp: |
| 67 | + outIDW = Idw(i, "Elevation", 2000, 2, RadiusVariable(10, 50000)) |
| 68 | + outIDW.save("elev_" + str(count) + ".tif") |
| 69 | + count = count + 1 |
| 70 | + |
| 71 | + |
| 72 | + |
| 73 | +# Task - Now we have run through the generation and partitioning of the input shapefile, and created a |
| 74 | +# rudimentary interpolation using IDW. We need to validate the file. You should consider the steps you need to |
| 75 | +# undertake to validate each partition. I have given you a run down below: |
| 76 | + |
| 77 | +# 1. You need to list the "test" files, see line 58... |
| 78 | +# 2. For each IDW and each test file (they share numbers... so you can use a count variable to iterate this, |
| 79 | +# you need to use ExtractValuesToPoints (in_point_features, in_raster, out_point_features) to pull the test |
| 80 | +# values from the "test" shapefile. |
| 81 | +# 3. Use the code I provide below to get yourself a correlation value for the interpolation. |
| 82 | + |
| 83 | +# arr = arcpy.da.FeatureClassToNumPyArray("elev_" + str(count) + "_valid.shp", ["Elevation", "RASTERVALU"]) |
| 84 | +# print "Interpolation " + str(count) + " correlation = " + str(pearsonr(arr["Elevation"], arr["RASTERVALU"])) |
| 85 | + |
| 86 | +# 4. Store the correlation value (hint the pearsonr outputs a tuple), take the mean of the total k-fold (hint sum / length). |
| 87 | + |
| 88 | +# 5. Take a mean of all the interpolated surfaces you generated and store it as an output (Hint: |
| 89 | +# https://pro.arcgis.com/en/pro-app/tool-reference/spatial-analyst/cell-statistics.htm |
| 90 | + |
| 91 | +# 6. Take a standard deviation of all the interpolated surfaces you generated and store it as an output (Hint: |
| 92 | +# https://pro.arcgis.com/en/pro-app/tool-reference/spatial-analyst/cell-statistics.htm |
| 93 | + |
| 94 | +# 6. Add clean up code to remove temporary files. |
| 95 | + |
| 96 | +test_shp = arcpy.ListFeatureClasses("*test*") |
| 97 | +pearson_values = [] |
| 98 | +raster_list = [] |
| 99 | + |
| 100 | +for fc in test_shp: |
| 101 | + run = fc.split("_") |
| 102 | + arcpy.gp.ExtractValuesToPoints_sa(fc, "elev_" + str(run[1]) + ".tif", "elev_" + str(run[1]) + "_valid.shp", "NONE", "VALUE_ONLY") |
| 103 | + arr = arcpy.da.FeatureClassToNumPyArray("elev_" + str(run[1]) + "_valid.shp", ["Elevation", "RASTERVALU"]) |
| 104 | + print "Interpolation " + str(run[1]) + " correlation = " + str(pearsonr(arr["Elevation"], arr["RASTERVALU"])) |
| 105 | + |
| 106 | + pearson_values.append(pearsonr(arr["Elevation"], arr["RASTERVALU"])[0]) |
| 107 | + raster_list.append("elev_" + str(run[1]) + ".tif") |
| 108 | + |
| 109 | + arcpy.Delete_management("elev_" + str(run[1]) + "_valid.shp") |
| 110 | + arcpy.Delete_management("elv_" + str(run[1]) + "_train.shp") |
| 111 | + arcpy.Delete_management("elv_" + str(run[1]) + "_test.shp") |
| 112 | + |
| 113 | +print "Overall mean: " + str(sum(pearson_values) / float(len(pearson_values))) |
| 114 | + |
| 115 | +outCellStats = arcpy.sa.CellStatistics(raster_list, "MEAN", "DATA") |
| 116 | +outCellStats.save("out_surface_mean.tif") |
| 117 | + |
| 118 | +outCellStats = arcpy.sa.CellStatistics(raster_list, "STD", "DATA") |
| 119 | +outCellStats.save("out_surface_std.tif") |
| 120 | + |
| 121 | +for i in raster_list: |
| 122 | + arcpy.Delete_management(i) |
| 123 | + |
| 124 | + |
| 125 | + |
| 126 | + |
| 127 | + |
| 128 | + |
| 129 | + |
| 130 | + |
| 131 | + |
| 132 | + |
| 133 | + |
| 134 | + |
| 135 | + |
0 commit comments