How to Expand a raster with many zone values

1770
8
Jump to solution
07-31-2019 05:34 AM
PatNussey
New Contributor II

I am using ArcMap 10.6.1 and I need to expand a large raster with thousands of zones by 1 cell using either the expand tool or a map algebra expression.  How can I write the expression to expand all zones in the input raster without entering each zone value separately.  Is there a way to write it so it expands zones from one number through to another? So for a range of raster values from the input raster. 

0 Kudos
1 Solution

Accepted Solutions
PatNussey
New Contributor II

Thank you for the suggestions.  I have found that the Euclidean Allocation tool seems to do the same thing if you set the distance to a multiple of the raster cell size. 

View solution in original post

8 Replies
DanPatterson_Retired
MVP Emeritus

I hope your zones aren't adjacent to one another since they might self obliterate.

You can copy and paste a zone list (not tried) using numpy.

import numpy as np
zones = np.arange(100)

zones
 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
       34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
       51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
       68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
       85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99])

# ---- just copy the list out like so
[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
       34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
       51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
       68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
       85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
0 Kudos
PatNussey
New Contributor II

It is a really big raster with over 700,000 zones, so this approach might be too cumbersome.  Is there a way to describe the zones by calling on the input raster's attribute table to iterate through the values? 

0 Kudos
DanPatterson_Retired
MVP Emeritus

This begs the question why are you expanding the zones?

Is it because it was a point file and you can't see them?

What do the zones represent? 

It is hard to picture an attribute represented by an integer as having 700,000 classes

0 Kudos
PatNussey
New Contributor II

It is a step in a model that was build with ArcInfo that does not seem to be accepted in ArcGIS Desktop.  The expand step follows a Region Group function on a raster to assign a unique ID to each contiguous raster area.  The expand step, I believe is to remove small gaps between region groups. The map algebra expression in the old model is: 

expand(wetrg, 1, table, %Workspace%\wetrg.vat)

Where wetrg is the region group output raster from the previous step.  The workspace has been specified in the environment settings. 

0 Kudos
DanPatterson_Retired
MVP Emeritus

So you have 700, 000 unique zones.  If you are trying to remove the fiddly-bits (aka, small areas), you normally query your zones on a size threshold as a precursor to using Nibble 

Nibble—Help | ArcGIS Desktop 

How Nibble works—Help | ArcGIS Desktop this too

0 Kudos
curtvprice
MVP Esteemed Contributor

It sounds like you are trying to replicate an existing workflow so I'm going to go back to Expand.

The 10x Expand syntax is:

Expand (in_raster, number_cells, zone_values)
‍‍‍

where zone_values is a python list of integers.

You can make a unique list from the VAT and use that variable with the Expand tool in Python like this. (If in_raster doesn't work, you may have to create a table view of the raster with MakeTableView and pass that in its place.)  

vlist = [v[0] for v in arcpy.sa.SearchCursor(in_raster, "VALUE")]
exp = arcpy.sa.Expand(in_raster, 1, vlist)‍‍‍‍
exp.save("exp_raster.tif")‍‍‍‍‍‍

Within Model Builder I think this is a good use case for the Calculate Value tool so you don't need to build a string representation of your many thousand integer values:

# Calculate Value expression
f(r"%Input raster%")

# Code block
def f(in_raster):
    vlist = [v[0] for v in arcpy.sa.SearchCursor(in_raster, "VALUE")]
    exp = arcpy.sa.Expand(in_raster, 1, vlist)‍‍‍‍
    exp.save("exp_raster.tif")‍‍‍‍‍‍‍‍‍
    return exp.catalogPath

# Data type
Raster Dataset
0 Kudos
PatNussey
New Contributor II

Thank you for the suggestions.  I have found that the Euclidean Allocation tool seems to do the same thing if you set the distance to a multiple of the raster cell size. 

curtvprice
MVP Esteemed Contributor

Good plan! You didn't mention you were expanding into NoData areas. If that's the case Euclidean Allocation is definitely what you needed. Either that or Nibble which uses a mask to select areas to be filled.

0 Kudos