Select 数组中沿角度的索引

Select indices in an array along an angle

我有一个数据数组,比如一个 10 x 10 数组,如下所示

A=array([[ 50, 385,  67, 445, 336, 305,  48, 419, 106,  39],
       [217, 188, 139,  64, 258, 340, 188,  18,  58, 278],
       [201,  43, 457, 196, 149, 289, 350,  86, 495, 448],
       [379, 376, 217, 124, 264,  69, 378, 296, 200, 416],
       [234,  65, 420,  44, 489, 451,  46, 216, 136,  97],
       [470, 162, 183, 480, 149, 482, 456, 294,  89, 337],
       [164, 335, 443, 305,  30, 381, 341, 331, 149, 261],
       [389, 160, 448, 304,  30, 280, 333, 360, 166, 300],
       [ 63, 346, 321, 229, 432, 129, 100, 217,  83, 196],
       [218,  33, 430, 237, 225, 391, 393, 344, 457,  82]])

如果我随机 select 数据点 149 的索引,例如一个 45 度的角度,我想要 5 个数据点,我想要它 return 5 个数据的索引沿着那条 45 度线的点。如图here. My angles are in ranges of 45 degrees, i.e -45, -90, ..., 180. So I can have data around the selected index like this

在上面的例子中,它应该return数据点的索引

[149, 451, 378, 86, 58]

此代码有效:(使用 python 3.8 或更新版本):

A=list([[ 50, 385,  67, 445, 336, 305,  48, 419, 106,  39],
       [217, 188, 139,  64, 258, 340, 188,  18,  58, 278],
       [201,  43, 457, 196, 149, 289, 350,  86, 495, 448],
       [379, 376, 217, 124, 264,  69, 378, 296, 200, 416],
       [234,  65, 420,  44, 489, 451,  46, 216, 136,  97],
       [470, 162, 183, 480, 149, 482, 456, 294,  89, 337],
       [164, 335, 443, 305,  30, 381, 341, 331, 149, 261],
       [389, 160, 448, 304,  30, 280, 333, 360, 166, 300],
       [ 63, 346, 321, 229, 432, 129, 100, 217,  83, 196],
       [218,  33, 430, 237, 225, 391, 393, 344, 457,  82]])
    
def where_is_each_datapoint(A):
    places = dict()
    for r_i , row in enumerate(A):
        for c_i , col in enumerate(row):
            if col in places.keys():
                places[col].append((r_i,c_i))
            else:
                places[col] = [(r_i,c_i)]
    return places

places = where_is_each_datapoint(A)

point = 149
angle = 45
number_of_datapoints = 5

def get_row_col_steps(angle):
    if angle in [360, -360]:
        return (0,1)
    elif angle in [315, -45]:
        return (1,1)
    elif angle in [270, -90]:
        return (1,0)
    elif angle in [225, -135]:
        return (1,-1)
    elif angle in [180, -180]:
        return (0,-1)
    elif angle in [135, -225]:
        return (-1,-1)
    elif angle in [90, -270]:
        return (-1,0)
    elif angle in [45, -315]:
        return (-1,1)
    return (0,0)

def find_datapoints(all_datapoints,point,angle,places,number_of_datapoints):
    result_datapoints = []
    place_of_point = places[point]
    row_step, col_step = get_row_col_steps(angle)
    for place in place_of_point:
        possible_result = []
        place_row = place[0]
        place_col = place[1]
        for i in range(number_of_datapoints):
            try:
                if (next_place_row := place_row + row_step*i) > 0 and (next_place_col := place_col + col_step*i) > 0:  # <--- This part should change for python versions lower than 3.8
                    possible_result.append(all_datapoints[next_place_row][next_place_col])
            except:
                break
        if len(possible_result) == number_of_datapoints:
            result_datapoints.append(possible_result)
    return result_datapoints

print(find_datapoints(A,point,angle,places,number_of_datapoints))

对于低于 3.8 的 python 版本:

[...]
if place_row + row_step*i > 0 and place_col + col_step*i > 0:
    possible_result.append(all_datapoints[place_row + row_step*i][place_col + col_step*i])
[...]

输出:

[[149, 451, 378, 86, 58]]

解释:

  1. where_is_each_datapoint():这个函数得到一个类似于你的list,并得到一个dictionary,它是keysdata pointsvaluescoordinates。可能有多个 data points 具有相同的值,例如在此列表中,有三个 149
  2. get_row_col_steps():这个函数得到一个angle并给出一对(row_step, col_step),例如如果它得到45它将return(-1,1).
  3. find_datapoints(): 这个函数return都是data points。因为它可以是多个 data points 具有相同的值,所以它可以是几个解决方案,并且它可能是几组 data points 对于特定的 pointangle ,和 number_of_datapoints。例如,如果 point = 149angle = 45 ,但是 number_of_datapoints = 2;有 3 个解决方案:[149, 340][149, 451][149, 337]