I am trying to calcualate the statistics of a TIFF. The script should ignore the NoData value, but doesn't. What causes this?

import gdal
from gdalconst import *

# register all of the drivers

# open the image
ds = gdal.Open('test_slope.tif', GA_ReadOnly)

# get raster band 1
band = ds.GetRasterBand(1)

# set NoData value

# Calculate and print Statistics
stats = band.GetStatistics(0,1)
print stats

The results look like this

[-3.4028230607371e+38, 126.5991897583, -4.6432918375055e+37, 1.1680875238428e+38]

GetStatistics will reuse previously computed statistics if they exist (i.e computed before you set the NoData value). You can use stats = band.ComputeStatistics(0) instead of GetStatistics to force the statistics to be recomputed.

  • ComputeStatistics worked. It ignored the nodata value. Thanks!
    – ustroetz
    Mar 12 '13 at 17:35

The API documentation doesn't specify how NoData is used when calculating statistics. All clues in your results demonstrate that NoData was not ignored in the statistical calculations, which is a pity.

I normally use a masked array to make calculations on arrays with missing values:

import numpy as np

# Read into NumPy array
array = band.ReadAsArray()

nodata = band.GetNoDataValue()
if nodata is not None:
    array = np.ma.masked_equal(array, nodata)

print('min: %s, max: %s, mean: %s, std: %s' %
      (array.min(), array.max(), array.mean(), array.std()))

Lastly, if you had opened the raster with GA_Update mode, you can write these to the data source:

band.SetStatistics(np.asscalar(array.min()), np.asscalar(array.max()),
                   np.asscalar(array.mean()), np.asscalar(array.std()))
  • The masked array also does not ignore the NoData Value.
    – ustroetz
    Mar 12 '13 at 17:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.