Skip to content

Commit

Permalink
Compute Non-standard Statistics
Browse files Browse the repository at this point in the history
Allow computation of statistics not directly implemented by the program
or the np.ma package.

Added two options:
add_stats = [‘stat1’, ‘stat2’]   # List of statistics to be computed
add_func=‘myfunc’    # Module where the functions that compute these
statistics are defined
  • Loading branch information
ozak committed Nov 30, 2014
1 parent 58da02d commit c76fd74
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/rasterstats/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ def raster_stats(*args, **kwargs):

def zonal_stats(vectors, raster, layer_num=0, band_num=1, nodata_value=None,
global_src_extent=False, categorical=False, stats=None,
copy_properties=False, all_touched=False, transform=None):
copy_properties=False, all_touched=False, transform=None,
add_stats=[None], add_func=[None]):
"""Summary statistics of a raster, broken out by vector geometries.
Attributes
Expand Down Expand Up @@ -78,6 +79,9 @@ def zonal_stats(vectors, raster, layer_num=0, band_num=1, nodata_value=None,
transform : list of float, optional
GDAL-style geotransform coordinates when `raster` is an ndarray.
Required when `raster` is an ndarray, otherwise ignored.
add_stats : List with name additional statistics to compute, optional
Each name in add_stats is a string with the name of a function
that takes Numpy (masked) matrices and computes and returns a statistic
Returns
-------
Expand Down Expand Up @@ -296,6 +300,19 @@ def zonal_stats(vectors, raster, layer_num=0, band_num=1, nodata_value=None,
except KeyError:
rmax = float(masked.max())
feature_stats['range'] = rmax - rmin
if add_stats:
if add_func:
try:
exec('from '+add_func+' import *')
except:
print('Could not load module %s') % add_func
break
for mystat in range(len(add_stats)):
adstat=add_stats[mystat]
try:
exec('feature_stats["'+adstat+'"] = '+adstat+'(masked)')
except:
print('Statistic %s in add_stats not defined in add_func') % adstat

# Use the enumerated id as __fid__
feature_stats['__fid__'] = i
Expand Down
7 changes: 7 additions & 0 deletions tests/myfunc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env python
# Additional functions to be used in raster stat computation
from __future__ import division
import numpy as np

def mymean(x):
return np.ma.mean(x)
12 changes: 12 additions & 0 deletions tests/test_zonal.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
OGRError, feature_to_geojson, bbox_to_pixel_offsets
from shapely.geometry import shape, box
import json
import sys

sys.path.append(os.path.dirname(os.path.abspath(__file__)))

DATA = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
raster = os.path.join(DATA, 'slope.tif')
Expand Down Expand Up @@ -389,3 +392,12 @@ def test_featurecollection():
# geointerface featurecollection
stats2 = zonal_stats(df, raster)
assert stats == stats2

def test_add_stats():
from geopandas import GeoDataFrame
polygons = os.path.join(DATA, 'polygons.shp')
df = GeoDataFrame.from_file(polygons)
mymean= lambda x: np.ma.mean(x)
stats = zonal_stats(df.geometry, raster, add_stats=['mymean'], add_func='myfunc')
for i in range(len(stats)):
assert stats[i]['mean'] == stats[i]['mymean']

0 comments on commit c76fd74

Please sign in to comment.