I am carrying out a spectral feature extraction in Python 3 starting from an 8-band image and a shapefile (consisting of about a million polygons) superimposed on it. I calculate the mean and standard deviation of the pixels for each polygon and join them to the polygon as additional attributes. The most intuitive way was to use the zonal_stats module which automatically saves the result in geojason (maintaining geographic information). The rest of the code allows merging the individual geojasons into one. The process, in particular the calculation of the spectral features, takes 21 hours. Given that I am a beginner with Python and with the world of programming, how could I implement multiprocessing in order to reduce processing times?
P.S .: My goal is to have a shp or geojason file with the spectral features calculated for each polygon and to drastically reduce the processing time. I use a workstation in which an Intel Xeon processor with 12 physical cores and 24 virtual cores.
from rasterstats import zonal_stats
polig = '...\\poligons.shp'
img_Berg = '....\\8_band_image.tif'
col = ['mean', 'std']
#the most demanding part of code starts from here ....
def zstats(b):
zs = zonal_stats(polig, img_Berg, band=b, stats=['mean', 'std'], geojson_out=True)
return zs
stats_blu = zstats(4)
stats_green = zstats(7)
stats_red = zstats(6)
stats_rededge = zstats(8)
stats_nir1 = zstats(5)
stats_nir2 = zstats(3)
stats_gndvi = zstats(1)
stats_dsm = zstats(2)
#.....to here
def change_name(d):
for i in range(len(d)):
a = d[i]['properties']
if d == stats_blu:
a['mean_blu'] = a.pop('mean')
a[' std_blu'] = a.pop('std')
elif d == stats_green:
a['mean_green'] = a.pop('mean')
a[' std_green'] = a.pop('std')
elif d == stats_red:
a['mean_red'] = a.pop('mean')
a[' std_red'] = a.pop('std')
elif d == stats_rededge:
a['mean_rededg'] = a.pop('mean')
a[' std_rededg'] = a.pop('std')
elif d == stats_nir1:
a['mean_nir1'] = a.pop('mean')
a[' std_nir1'] = a.pop('std')
elif d == stats_nir2:
a['mean_nir2'] = a.pop('mean')
a[' std_nir2'] = a.pop('std')
elif d == stats_gndvi:
a['mean_gndvi'] = a.pop('mean')
a[' std_gndvi'] = a.pop('std')
elif d == stats_dsm:
a['mean_dsm'] = a.pop('mean')
a[' std_dsm'] = a.pop('std')
return(d)
a = change_name(stats_blu)
b = change_name(stats_green)
c = change_name(stats_red)
d = change_name(stats_rededge)
e = change_name(stats_nir1)
f = change_name(stats_nir2)
g = change_name(stats_gndvi)
h = change_name(stats_dsm)
def merge(a, b, c, d, e, f, g, h):
l = [a, b, c, d, e, f, g]
for i in range(len(a)):
for j in l:
z = j[i]['properties'].copy()
h[i]['properties'].update(z)
merge(a, b, c, d, e, f, g, h)
Output_geoj = h.copy()