[GRASS-user] average calculation

Glynn Clements glynn at gclements.plus.com
Thu May 14 20:05:11 EDT 2009


Seb wrote:

> If one were to calculate an average of several rasters, one could simply
> do:
> 
> r.mapcalc "ave = (A + B + C) / 3"
> 
> But how can we get around the problem of null values in any of the
> rasters, which would propagate it to the result?  What is an efficient
> way to calculate both the numerator and denominator for each pixel so
> that it corresponds only to rasters with non-null values.

As Hamish says, "r.series method=average ...".

For r.mapcalc:

	r.mapcalc <<-EOF
		ave = eval(\
		n_A = isnull(A), n_B = isnull(B), n_C = isnull(C),\
		((n_A ? 0 : A) + (n_B ? 0 : B) + (n_C ? 0 : C))\
		 / (!n_A + !n_B + !n_C))
	EOF

>  A second
> problem is how to script this (shell) so that a large number of rasters
> can be included in this calculation.

	maps="map1 map2 map3 map4"
	(
	  echo "ave = eval(\\"
	  for map in $maps ; do
	    echo "n_$map = isnull($map),\\"
	  done
	  echo "(0\\"
	  for map in $maps ; do
	    echo " + (n_$map ? 0 : $map)\\"
	  done
	  echo ") / (0\\"
	  for map in $maps ; do
	    echo " + !n_$map\\"
	  done
	  echo "))"
	) | r.mapcalc

Using a real language would produce more legible code; e.g. in Python:

	import subprocess
	maps = ['map1', 'map2', 'map3', 'map4']
	nulls = ["n_%s = isnull(%s)" % (m, m) for m in maps]
	numer = ["(n_%s ? 0 : %s)" % (m, m) for m in maps]
	denom = ["!%s" % m for m in maps]
	expr = "ave = eval(%s,(%s) / (%s))" % (",".join(nulls), " + ".join(numer), " + ".join(denom))
	subprocess.call(['r.mapcalc', expr])

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the grass-user mailing list