I have a grid dataset of 2.5km grid-cells and want to calculate the average of some attributes for each of the eight adjacent cells to the central one (nine cells forming a square). So the calculation of average should actually exclude the attribute value of the grid cell it is applied to. There are also 'holes' in my grid, i.e. I have removed cells with zero population beforehand, because they do not matter to my research and to limit the amount of features to be dealt with. Therefore, not all grid cells have 8 neighbouring cells, this can vary from 0-8.

My question is similarly dealt with elsewhere, but I can't seem to come to a satisfying result; e.g. here: Getting values from adjacent polygons or nearest point

or similarly here: Calculating average data of neighbour grids based on location and returning data to grid in QGIS

I have tried array_mean (overlay_touches( @layer,myfield)) and it seems to get the right results in a test-dataset, but it is too slow for my > 1 million grid cells dataset.

Secondly, I tried array_mean (overlay_nearest( @layer,myfield, limit:=8, max_distance:= 3.0177)) and it seems quite fast, but strangely results vary in validity. The max_distance I applied represents the calculated distance between centroids of grid cells lying diagonally to the base cell. Unfortunately, the calculation of the average value of the 'central cell' includes its own attribute value, but the average should only be calculated based on the surrounding ones. I also don't seem to be able to produce stable results: In the test layer the central cell value doesn't seem to be added, in the large layer it was. I also tried without the max_distance bit, which introduces the problem that in the case of cells with < 8 neighbours, the average of non-neighbouring cells is being added in the calculation, I suppose.

My question is: How can I calculate (in an as-fast-as-possible calculation time for > 1 mio grid cells) the average value of n surrounding grid cells of a respective central grid cell (with n of surrounding cells actually varying between 0-8) and apply it to a new field (i.e. not including the value of the feature itself in the calculation)?

  • Welcome to GIS SE. Thank you for taking the Tour. Unfortunately, you seem to have missed the emphasis on asking One question per Question.. Please Edit this Question to ask one question.
    – Vince
    Jan 31, 2022 at 22:07

1 Answer 1


Nearest neighbor calculations are a very basic procedure when working with raster data. For example the GRASS GIS module r.neighbor can calculate a nearest neighbor raster by averaging cells within a window size. Furthermore you can specify a "weights" file to set which cells to ignore (the center cell in the window in your case). See the manual page for further details. In order to ignore the center cell, your weights file would be:

1 1 1
1 0 1
1 1 1

I'm quite sure that switching to raster will be much faster than any vector attribute procedure. The above GRASS GIS module, as well as other neighborhood processing modules, is available from the QGIS processing toolbox. I suggest to convert your grid to raster and choose whatever raster module suits you in this case.

  • The algorithm fails if I specify a weights file as you suggested (i created a simple txt file containing the numbers). Tested without a weights file and it works. Do I have to set region extent or cellsize or some other parameter for the weight file to work? (the mentioned ones are optional, so shouldn't make a difference?)
    – JiannisK
    Feb 23, 2022 at 23:50
  • The weights file should be a simple text file. Just three lines as above. What output do you get when you run with the weights file? Is this in QGIS or directly in GRASS?
    – Micha
    Feb 24, 2022 at 10:53
  • I am doing it in QGIS version: 3.22.4-Białowieża (Python version: 3.9.5 GDAL version: 3.4.1); with grass version 7 - the log shows input parameters: { '-a' : False, '-c' : False, 'GRASS_RASTER_FORMAT_META' : '', 'GRASS_RASTER_FORMAT_OPT' : '', 'GRASS_REGION_CELLSIZE_PARAMETER' : 0, 'GRASS_REGION_PARAMETER' : None, 'gauss' : None, 'input' : 'C:/...', 'method' : 0, 'output' : 'TEMPORARY_OUTPUT', 'quantile' : '', 'selection' : None, 'size' : 3, 'weight' : 'C:\\....\\weight.txt' } - could it be that the algorithm is messing up the path with the \\?
    – JiannisK
    Feb 24, 2022 at 11:06
  • continued: In between command lines it says: Starting GRASS GIS... WARNUNG: Sperren gleichzeitiger Zugriffe auf ein Mapset ist unter Windows nicht möglich. .... and then later: Die Standard Region wurde auf die neue Projektion aktualisiert. Wenn Sie aber mehrere Mapsets haben, sollten Sie g.region -d in jedem ausführen, um die Einstellungen von der Standardregion zu übernehmen. Projektionsinformationen aktualisiert .... FEHLER: Rasterkarte <outputc29704f0c8894750b8802698c6edf69e> konnte nicht gefunden werden. .... but it works nicely if I just leave the weights file empty
    – JiannisK
    Feb 24, 2022 at 11:12
  • Sorry, I don't understand the German message. Can you try to run the module directly in GRASS? (to isolate any possible Processing Toolbox erros)
    – Micha
    Feb 26, 2022 at 15:51

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.