# Creating NDVI from raster using ArcPy

I have to create NDVI's for multiple raster images, and so want to find out the most efficient way to do it.

The code below works, but I wondered if there was a more efficient way to do it?

# Strip out the red and near infrared bands
arcpy.CompositeBands_management(input_raster + r"\Band_3", "raster_red")
arcpy.CompositeBands_management(input_raster + r"\Band_4", "raster_nearir")

# Create the ndvi numerator and denominators
arcpy.Minus_3d("raster_nearir", "raster_red", "numerator")

arcpy.Plus_3d("raster_nearir", "raster_red", "denominator")

# Set local variables
top = arcpy.sa.Raster("numerator")
bottom = arcpy.sa.Raster("denominator")

# Execute Divide
raster_ndvi = top / bottom

# Save the output
raster_ndvi.save("ndvi_result")```
• Also, if anyone can explain how to use GenerateRasterFromRasterFunction to do this(see arc pro documentation here) I would be much obliged. Jan 20, 2020 at 13:48
• Ooops, sorry! Thanks again for your assistance here :) Jan 21, 2020 at 11:13

I would do something like this:

from arcpy.sa import *

input_raster = 'path/to/raster'

red = Float(Raster(input_raster + r"\Band_3"))
nir = Float(Raster(input_raster + r"\Band_4"))

ndvi = (nir - red) / (nir + red)

ndvi.save("ndvi_result")

You could also use GenerateRasterFromRasterFunction_management, but that seems to take much the same processing time

import time

from arcpy.sa import *

input_raster = r"c:\temp\LC80900812014223LGN00.TIF"  # Some Landsat 8 data

s = time.time()
red = Float(Raster(input_raster + r"\Band_4"))    # Band names are 1 indexed
nir = Float(Raster(input_raster + r"\Band_5"))

ndvi = (nir - red) / (nir + red)

ndvi.save("c:/temp/ndvitest1.tif")

print("Map algebra:", time.time() - s)

s = time.time()
arcpy.GenerateRasterFromRasterFunction_management(
raster_function="NDVI",
out_raster_dataset=r"c:\temp\ndvitest2.tif",
raster_function_arguments=r"Raster c:\temp\LC80900812014223LGN00.TIF; VisibleBandID 3;InfraredBandID 4;ScientificOutput 1",  # Bands are 0 indexed
format="TIFF")
print("GenerateRasterFromRasterFunction:", time.time() - s)
Map algebra: 17.283000230789185
GenerateRasterFromRasterFunction: 17.730000257492065
• Thanks @user2856, this is a lot more succinct than my code, but has more or less the same runtime. Have you ever come across GenerateRasterFromRasterFunction - arcpro raster functions? And do you think it can be used for this purpose? Jan 20, 2020 at 13:42
• @AndrewEinhorn See edit Jan 21, 2020 at 0:30
• Thanks a million for the demonstration! Try as I might, when I run the following code, I get an error. Can you see where I'm going wrong? from arcpy.sa import * arcpy.GenerateRasterFromRasterFunction_management(raster_function="NDVI", out_raster_dataset=r"D:\output_image.tif", raster_function_arguments=r"Raster D:\input_image.tif; VisibleBandID 3; InfraredBandID 4; ScientificOutput 1", format="TIFF") arcgisscripting.ExecuteError: Parameters are not valid. ERROR 000814: Invalid file type ERROR 000840: The value is not a String Failed to execute (GenerateRasterFromRasterFunction) Jan 21, 2020 at 6:31
• Looks ok to me, suggest you ask a new question and provide your code, the error, full details of the input raster, and whether you can apply the ndvi raster function manually via ArcGIS Pro (not GenerateRasterFromRasterFunction, just the function itself). Jan 21, 2020 at 7:52