Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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
gdal.AllRegister()

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

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

# set NoData value
band.SetNoDataValue(-3.4028230607371e+38)

# 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]
>>> 
share|improve this question
    
don't cross-post: stackoverflow.com/questions/15351104/… –  Mike T Mar 26 '13 at 2:04
add comment

2 Answers 2

up vote 4 down vote accepted

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.

share|improve this answer
    
ComputeStatistics worked. It ignored the nodata value. Thanks! –  ustroetz Mar 12 '13 at 17:35
add comment

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()))
share|improve this answer
    
The masked array also does not ignore the NoData Value. –  ustroetz Mar 12 '13 at 17:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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