Search code examples
pythonnumpy-ndarrayvalueerror

I want to compare a 2d numpy array to find that data is lies between the range or not if yes than it should be append in new group


I want to compare 2d numpy array with the single x_min , x_max and same for the value of y but I didn't understand the concept of loop in this case how to define loop to compare and use numpy.where_logical_and.

import numpy as np

group_count = 0
xy = np.array([[116,2306],[118,2307],[126,1517]])
idx = np.array([[0,0],[0,1]])
group1 = []

for l in xy:
    for i in idx:
        for j in range(1):
            x_temp = xy[idx[i][j]]
            x1 = x_temp[0][0]
            y1 = x_temp[0][1]
            x1_max = x1 + 60
            x1_min = x1 - 60
            y1_max = y1 +60
            y1_min = y1 - 60
            range_grp_1 = [x1_max,x1_min,y1_min,y1_max]
            grp1 = [x1,y1]
            grp_1 = np.array(grp1)
            #print(grp_1,range_grp_1)
            if group_count != 0:
                print('group count greater than 0')
                if np.where((l[i]>x1_min) and (l[i]<x1_max) and (l[i]>y1_min) and (l[i]<y1_max)):
                    print(l[i])

            else:
                group1.append(grp_1)
                group_count+=1

Error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Solution

  • I post a new code here.

    As you said you have a lot of points and the ranges seems to variate, I propose you to wrap the control inside a function, so you can call it as many times as you need to, passing the range of coordinates to be evaluated.

    # function to return max and min of list of coordinates
    def  min_max(coords):   
    
       xy = np.array(coords)
    
       xs = [] #save 'x' values
       for i in range(len(xy)):
            x = [xy[i][0]]
            xs.append(x)   
    
       ys = [] #save 'y' values
       for i in range(len(xy)):
            y = [xy[i][1]]
            ys.append(y)
    
       rangex    = []
       rangey    = []
    
       for x in min(xs): #get min 'x'
           minx = x - 60
           rangex.append(minx)
           maxx = x + 60
           rangex.append(maxx)
    
       for y in min(ys):  #get min 'y'
            miny = y - 60
            rangey.append(miny)
            maxy = y + 60      
            rangey.append(maxy)
    
       return [rangex,rangey]
    

    If you pass the same coordinates you posted the first time, it returns

        Execution #1:
        coords = [[116,2306],[118,2307],[126,1517]]
        my_ranges = min_max(coords)
        print(my_ranges)
        #[[56, 176], [1457, 1577]]
    

    Or if you pass just the new range you gave me:

       Execution #2:
       new_coord = [[518,2007]]#pay attention to the format
       my_ranges = min_max(new_coord)
       print(my_ranges)
       #[[458, 578], [1947, 2067]]
    

    And the last part of the code. The one that separates the groups if they belongs to the evaluated range or not.

       #changed again:
       group1 = [] #coords in the interval
       group2 = [] #coords out of the interval
    
       for l in dynCoords:
            pair = [l[0],l[1]]  
            if l[0] in range(my_ranges[0][0],my_ranges[0][1]) and l[1] in range(my_ranges[1][0],my_ranges[1][1]):
                     group1.append(pair)
            else:
                     group2.append(pair)
    
       #new line appended
       my_ranges = min_max(group2) 
    

    With the original coordinates [[116,2306],[118,2307],[126,1517]] the groups [118,2307],[126,1517] got out of the range, and went to group2. With the new line appended they were used to change the minimun threshold again, now it goes from 56-2246 for xs and 176-2366 for ys. Let's say you use group2 in dynCoords, dynCoords = group2 and execute what goes under the label #changed again, you get for group1: [[116, 2306], [118, 2307]] and group2 goes empty.

    I think you can make a function for that part of the code too. And run it as many times as you need to treat all your coordinates set.