Array multiband processing with numpy

2127
1
06-03-2014 03:12 PM
bogdanpalade1
New Contributor III
Hello,

My problem is about processing of multibands rasters using numpy. For example in the case when you have a lets say 10 bands raster, I would like to have an algorithm that would tell me if, passing from band 1 to band 10, the pixel values are in increasing or decreasing order, or if they satisfy other functions like increasing and then decreasing values or decreasing and then increasing values, or if they are just constant. With help from other forums I have written the function bellow (incDec(b)) which satisfies all my conditions.
My problem is how to implement this in a numpy array in order to check if the pixels fulfill this condition on the first axis (the bands axis).
Oh, something that I did not mentioned is that 0 values have to be disregarded from all the calculations as you can see from the code below.

def decrease(a):
    return all(a >= a[i+1] for i in range(len(a)-1)) # function to check if a list has decreasing values
def increase(a):
    return all(a <= a[i+1] for i in range(len(a)-1))  # function to check if a list has increasing values

b = [1,2,3,4,5,4,3,2]
def incDec(b):
    a=[value for value in b if value !=0]
    r = a.index(max(a))
    s=a.index(min(a))
    inc=a[:r]
    dec=a[r:]
    inc2=a[:s]
    dec2=a[s:]
    if all(a <= a[i+1] for i in range(len(a)-1))==1:
        return "increasing"
    elif all(a >= a[i+1] for i in range(len(a)-1))==1:
        print "decreasing"
    elif increase(inc)==1 and decrease(dec)==1:
        return "increasing decreasing"
    elif decrease(inc2)==1 and increase(dec2) ==1:
        return "decreasing increasing"
    else:
        return"mixed"
 
print incDec(b) 


So, in conclusion, I would like to run this function on a three dimensional array instead of a list ( like in the example above- the list b) in order to see how pixel values change from band to band.

Thank you very much,

Bogdan
Tags (2)
0 Kudos
1 Reply
RonaldBeloin
New Contributor II
I imagine the OP has figured this out by now, but for those of you listening...

Numpy has some functional programming.
I only had to change the function supplied in the question to return integers.
Then applied the numpy.apply_along_axis function on a test array:

def decrease(a):
    return all(a >= a[i+1] for i in range(len(a)-1)) # function to check if a list has decreasing values
def increase(a):
    return all(a <= a[i+1] for i in range(len(a)-1))  # function to check if a list has increasing values

def incDec(b):
    a=[value for value in b if value !=0]
    r = a.index(max(a))
    s=a.index(min(a))
    inc=a[:r]
    dec=a
    dec2=a for i in range(len(a)-1))==1:
        return 1 # "increasing"
    elif all(a >= a[i+1] for i in range(len(a)-1))==1:
        return -1 # "decreasing"
    elif increase(inc)==1 and decrease(dec)==1:
        return 2 # "increasing decreasing"
    elif decrease(inc2)==1 and increase(dec2) ==1:
        return -2 # "decreasing increasing"
    else:
        return 0 # mixed

# make test array 2 X 2 X 8 bands
# assuming x and y pixels, with 8 bands
b = [1,2,3,4,5,4,3,2]
c = [1,2,3,4,5,6,7,8]
d = [8,7,6,5,4,3,2,1]
e = [8,7,6,5,6,7,8,9]
nb = np.array(b)
nc = np.array(c)
nd = np.array(d)
ne = np.array(e)
narr = np.indices((2,8))
narr[:] = np.array([[nb,nc],[nd,ne]])

print np.apply_along_axis(incDec, 2, narr)


Ron
0 Kudos