You are right that exec
is frowned upon and I think you will be better suited to use arrays and numpy
to solve your problem than using the raster calculator.
I assume that all of the rasters in your list have the same number of rows and columns because you talk about merging the results at the end. The following will result in:
- 1 for cells where none of the rasters have values between 0 and 367 in the cell
- 0 for cells where at least 1 of the rasters has a value between 0 and 367 in the cell
I am fairly certain that is what you want.
This first section of code gets all of the variables you will initially need:
#set the lower and upper values
lower_break_value = 0
upper_break_value = 367
#get raster list, properties of first raster to create out_raster_data to hold results
list_rasters = arcpy.ListRasters('*', "TIF")
temp_raster = arcpy.Raster(list_rasters[0])
raster_rows = temp_raster.width
raster_columns = temp_raster.height
out_raster_data = numpy.ones((raster_columns, raster_rows), numpy.int) #in your question you only refer to integer values but this can be changed
The following section uses a loop on the rasters in your list to do the following for each raster:
- create a numpy array from the raster
- use
numpy.where
to classify values that are greater than your lower_break_value
(0)
- use
numpy.where
to classify the values that are less than your upper_break_value
(367). numpy.where
can only evaluate one condition so we have to break it up into two separate statements.
- add the two resulting arrays from the
numpy.where
operations. Anything that meets both conditions will add to 0.
- create a
temp_mask
that sets all values to True that do not equal 0 and False that equal 0
add temp_mask
to a list bands_list
bands_list = []
for i in list_rasters:
temp_array = arcpy.RasterToNumPyArray(i).astype(numpy.int)
greater_than = numpy.where(temp_array > lower_break_value, 0, temp_array)
less_than = numpy.where(temp_array < upper_break_value, 0, temp_array)
temp_result = greater_than + less_than
temp_mask = temp_result != 0
bands_list.append(temp_mask)
In the final portion of code we loop over the masked arrays in band_list
and multiply them by out_raster_data
which is just an array of ones. Any cell in any of the arrays\rasters that was between 0 and 367 is a 0, therefore when we multiply it by the other values it will result in a 0 in out_raster_data
:
for i in range(0, len(bands_list)):
out_raster_data *= bands_list[i]
#convert out_raster_data to a raster and save the results
result_raster = arcpy.NumPyArrayToRaster(out_raster_data)
result_raster.save(r'') #enter output raster path here