Python 中按浮点值切片的二维数组

2D array slicing by float value in Python

我想用 Python 3.x 中的 x 值对 [x,y] 坐标对数组进行切片,其方式与 this 问题的解决方案类似,但是坐标而不是一维列表。

例如,对于 (numpy) 坐标数组,我想要一个像这样的函数:

coords = np.array([[1.5,10],[2.5,20],[3.5,30],[4.5,40],[5.5,50]])
def slice_coords_by_x(xmin, xmax, arr):
    *some function*
slice_coords_by_x(2, 4, arr)
>>>[[2.5,20],[3.5,30]]

如果解决方案包含或不包含 xmin 和 xmax,则不要过分挑剔,因为我将在超过 1000 左右的大范围内使用它。

切片并创建具有此类 min-max 限制的掩码,因此 select 行具有 boolean-indexing -

def slice_coords_by_x(arr, xmin, xmax):
    return arr[(arr[:,0] >= xmin) & (arr[:,0] <= xmax)] 

样品运行 -

In [43]: arr
Out[43]: 
array([[  1.5,  10. ],
       [  2.5,  20. ],
       [  3.5,  30. ],
       [  4.5,  40. ],
       [  5.5,  50. ]])

In [44]: slice_coords_by_x(arr, xmin=2, xmax=4)
Out[44]: 
array([[  2.5,  20. ],
       [  3.5,  30. ]])

In [45]: slice_coords_by_x(arr, xmin=1, xmax=5)
Out[45]: 
array([[  1.5,  10. ],
       [  2.5,  20. ],
       [  3.5,  30. ],
       [  4.5,  40. ]])

如果没有 numpy,您可以为此使用 bisect 来找到插入点。请注意,该参数是一个列表(我将 None 添加为第二个参数,如 here 中所示,但它没有用)。

import bisect

coords = [[1.5,10],[2.5,20],[3.5,30],[4.5,40],[5.5,50]]

def slice_coords_by_x(lower,upper,arr):
    l=bisect.bisect_left(arr,[lower])
    u=bisect.bisect_right(arr,[upper])
    return arr[l:u]

print(slice_coords_by_x(2,4,coords))

结果:

[[2.5, 20], [3.5, 30]]

bisect 要求列表已排序(似乎是这样),否则将不起作用。

未排序

如果给定的点列表是无序的,您可以使用 filter,并使用 list 实现:

def slice_coords_by_x(xmin,xmax,arr):
    return list(filter(lambda p: xmin < p[0] < xmax,arr))

您显然也可以将排序后的列表提供给此方法,但与下一种方法相比,这将花费更多时间。

排序列表

鉴于点 按 x-coordinate 排序,您可以使用 bisect 包:

def slice_coords_by_x(xmin,xmax,arr):
    left = bisect.bisect_left(arr,[xmin])
    right = bisect.bisect_right(arr,[xmax])
    return arr[left:right]

不应该简单

def slice_coords_by_x(xmin, xmax, arr):
    return [i for i in arr if xmin <= i[0] and i[0] <= xmax]

成功了吗?它可读、快速且易于访问。

可以对这个列表进行排序,甚至可以传递一个数组,但该方法应该易于访问,以便根据任何需要进行更改。