I want to create yearly average temperature for grid cells in a raster file based on monthly data. I have a multiband raster with 1380 bands, each corresponding to 1 month from 1900 till 2014. Now I would like to use python to read the .tif file, extract years by extracting 12 bands at a time (bands 1-12 for year 1900, bands 13-24 for year 1901 and so on), calculate the mean over the 12 extracted bands and save it in a new raster.

My approach was as follows:

india_temp = rio.open(r'monthly_mean_temp.tif')
year = {}
r = list(range(1,13))
integers = [12] * 12
for p in range(1900,2015):
    year[p] = india_temp.read(r) #read in 12 months/bands steps
    months1 = year[p].indexes
    month1 = dict()
    for i in months1:
        month1[i] = year[p].read(i)
    mean_band = np.mean(list(month1.values()))
    with rio.open(r'empty1.tif') as src:
        ras_data = src.read()
        ras_meta = dataset.profile

    # changes to raster properties:
    ras_meta['dtype'] = "float32"
    ras_meta['nodata'] = -99

    with rio.open(r'monthly_mean_temp_' + str(p) + '.tif', 'w', **ras_meta) as dst:
        dst.write(mean_band, 1)    
    for index, integer in enumerate(integers):
        r[index] += integer 

There are apparently several mistakes in the code and I tried some other coding as well but since I am quite new to python and QGis, I don't know what I could do to solve the issue.

1 Answer 1


No need to loop through each month, you can just pass an iterable of month indexes to the read method, e.g. src_dataset.read(indexes)

For example:

import rasterio as rio

years = (1900, 2015)

src_filename = 'monthly_mean_temp.tif'
dst_filename = 'yearly_mean_temp_{}.tif'

with rio.open(src_filename) as src:
    profile = src.profile

    for year in range(*years):
        start_month = (year-years[0]) * 12 + 1
        months = range(start_month, start_month+12)
        monthly_mean = src.read(months).mean(axis=0)
        with rio.open(dst_filename.format(year), "w", **profile) as dst:
            dst.write(monthly_mean, 1)

If you wanted to create yearly data beginning in July of each year, you could use:

start_month = ((year-years[0]) * 12 + 7)

But I haven't tested this so don't know if it will fail in the last year when you only have July-Dec instead of July-June.

  • That works perfectly! If I were to create yearly data, however beginning in July of each year, I would use start_month = ((year-years[0]) * 12 + 6), correct?
    – Hokkaido21
    Feb 22, 2022 at 9:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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