Conditional Statement

2211
16
07-04-2017 08:30 AM
johnmonks
New Contributor II

Hey, so, having frustraited over this for ages I give up and will ask

I have a conditional statement I applied to an NDVI layer to apply a double sided membership function to it

It is in 32 bit float as it is decimal. The following statement was used

Con((Float("spainndvi" < 0.13)) & (Float("spainndvi" > 0.9)), 0, Con((Float("spainndvi" >= 0.13)) & (Float("spainndvi" <= 0.32)), (Float("spainndvi" - 0.13)) / (0.32 - 0.13)), Con((Float("spainndvi" >= 0.6)) & (Float("spainndvi" <= 0.9)), (Float(0.9 - "spainndvi")) / (0.9 - 0.6), 1))

The odd thing is it worked when I last used it but having miss named the file I deleted it by accident, went to re-run the statement and it just gives me an error. Is there something obviously wrong with my statement? Thanks

0 Kudos
16 Replies
DanPatterson_Retired
MVP Emeritus

I worked with the generic form, it was getting too hard to follow, then I tried to back fill

Con((a < 0.13) & (a > 0.9), 0, then the rest.....
but it should have been
Con((a < 0.13) | (a > 0.9), 0, then the rest.....
0 Kudos
johnmonks
New Contributor II

Hey forgive my lack of insight but say for NDVI I thought the statement Con((Float("spainndvi") < 0.13) & (Float("spainndvi") > 0.9), 0 would specify that any number that is lower than 0.13 and higher than 0.9 will be attributed a value of 0? 

0 Kudos
DanPatterson_Retired
MVP Emeritus

that would be 'or'  ... a number can't be both... as in 'and', I can't remember off hand, but I think it is vertical bar '|' for or (I would have to check it up for the spatial analyst

a = 0.5    # start with a value of 0.5

(a < 0.3) & (a > 0.9)
Out[2]: False

(a < 0.3) | (a > 0.9)
Out[3]: False

a = 0.1    # try a new one with the same conditions

(a < 0.3) & (a > 0.9)
Out[5]: False

(a < 0.3) | (a > 0.9)
Out[6]: True

a = 1.     # let's go to the other possible side

(a < 0.3) & (a > 0.9)
Out[8]: False

(a < 0.3) | (a > 0.9)
Out[9]: True
0 Kudos
JayantaPoddar
MVP Esteemed Contributor

Hi John,

Could you try out the expression that I have mentioned in my above comment?



Think Location
0 Kudos
johnmonks
New Contributor II

Dan - I tried them both and it was indeed only taking one of the elements which was > 0.9 and therefor low values were given a wrong suitability, so much appreciated

Jayanta - I went back and tried the expression and it worked just fine and gave me the result I wanted as well so it seems that both ways work fine but I'm surprised it worked without the float because originally it was producing an integer result

Either way it produced the NDVI layer that I wanted so big thank you to you both

johnmonks
New Contributor II

Interestingly though, in regards to the brackets

Con(Float("tmp" > 8.64), 0, Con((Float("tmp" <= 8.64)) & (Float("tmp" >= 4.31)), (Float(8.64 - "tmp")) / (8.64 - 4.31), 1))

produced the same result as

Con(("tmp" > 8.64), 0, Con(("tmp" <= 8.64) & ("tmp" >= 4.31), (8.64 - "tmp") / (4.33), 1))

even though the brackets in the first one seem wrong.

0 Kudos
curtvprice
MVP Esteemed Contributor

Hey John,

This statement doesn't have much effect:

Float("tmp" > 8.64)‍‍‍

because you are floating a boolean result, so you get 1.0 if true 0.0 if false. It is more efficient just leave it as boolean.

You only get integer out of a divide ("/") operation if both the inputs are integer (or boolean). 

If you want to force a float raster out raster calculator, put a single Float() around the whole expression.

One more thing, you can avoid some code because of the "else" behavior of Con. If tmp has a value and is <= 8.64, this can be assumed to make it to the else expression.

These expressions are equivalent:

Con(("tmp" > 8.64), 0, Con(("tmp" <= 8.64) & ("tmp" >= 4.31), (8.64 - "tmp") / (4.33), 1))
Con(("tmp" > 8.64), 0, Con(("tmp" >= 4.31), (8.64 - "tmp") / 4.33, 1))‍‍‍‍
# both the folowing approaches will force a float raster output:
Con(("tmp" > 8.64), 0.0, Con(("tmp" >= 4.31), (8.64 - "tmp") / 4.33, 1.0))‍‍‍‍
Float(Con(("tmp" > 8.64), 0, Con(("tmp" >= 4.31), (8.64 - "tmp") / 4.33, 1))‍‍‍‍)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

* small update. To avoid the error message: "the truth value of a raster is ambiguous" you need parentheses around the comparison expressions.

https://community.esri.com/message/14091?sr=search&searchId=966e684e-305f-4ee4-9ca7-99a811458cfa&sea...

0 Kudos