Search code examples
arraysnumpygeometrydegrees

How to deal with circle degrees in Numpy?


I need to calculate some direction arrays in numpy. I divided 360 degrees into 16 groups, each group covers 22.5 degrees. I want the 0 degree in the middle of a group, i.e., get directions between -11.25 degrees and 11.25 degrees. But the problem is how can I get the group between 168.75 degrees and -168.75 degrees?

a[numpy.where(a<0)] = a[numpy.where(a<0)]+360
for m in range (0,3600,225):
        b = (a*10 > m)-(a*10 >= m+225).astype(float)    
        c = numpy.apply_over_axes(numpy.sum,b,0)

Solution

  • If you want to divide data into 16 groups, having 0 degree in the middle, why are you writing for m in range (0,3600,225)?

    >>> [x/10. for x in range(0,3600,225)]
    [0.0, 22.5, 45.0, 67.5, 90.0, 112.5, 135.0, 157.5, 180.0, 202.5, 225.0, 247.5,
     270.0, 292.5, 315.0, 337.5]
    ## this sectors are not the ones you want!
    

    I would say you should start with for m in range (-1125,36000,2250) (note that now I am using a 100 factor instead of 10), that would give you the groups you want...

    wind_sectors = [x/100.0 for x in range(-1125,36000,2250)]
    for m in wind_sectors:
        #DO THINGS
    

    I have to say I don't really understand your script and the goal of it... To deal with circle degrees, I would suggest something like:

    • a condition, where you put your problematic data, i.e., the one where you have to deal with the transition around zero;
    • a condition where you put all the other data.

    For example, in this case, I am printing all the elements from my array that belong to each sector:

    import numpy
    
    def wind_sectors(a_array, nsect = 16):
        step = 360./nsect
        init = step/2
        sectores = [x/100.0 for x in range(int(init*100),36000,int(step*100))]
    
        a_array[a_array<0] = a_arraya_array[a_array<0]+360
    
        for i, m in enumerate(sectores):
            print 'Sector'+str(i)+'(max_threshold = '+str(m)+')'
            if i == 0:
                for b in a_array:
                    if b <= m or b > sectores[-1]:
                        print b
    
            else:
                for b in a_array:
                    if b <= m and b > sectores[i-1]:
                        print b
        return "it works!"
    
    # TESTING IF THE FUNCTION IS WORKING:
    a = numpy.array([2,67,89,3,245,359,46,342])
    
    print wind_sectors(a, 16)
    
    # WITH NDARRAYS:
    
    b = numpy.array([[250,31,27,306], [142,54,260,179], [86,93,109,311]])
    
    print wind_sectors(b.flat[:], 16) 
    

    about flat and reshape functions:

    >>> a = numpy.array([[0,1,2,3], [4,5,6,7], [8,9,10,11]])
    >>> original = a.shape
    >>> b = a.flat[:]
    >>> c = b.reshape(original)
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
    >>> c
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])