简体   繁体   English

在Python中通过float值进行2D数组切片

[英]2D array slicing by float value in Python

I want to slice an array of [x,y] coordinate pairs by x value in Python 3.x, in a similar way to the solution to this question but with coordinates rather than a 1d list. 我想在Python 3.x中用x值切割[x,y]坐标对的数组,方法与问题的解决方案类似,但是使用坐标而不是1d列表。

For example for the (numpy) array of coordinates I want a function like: 例如,对于(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]]

Not overly fussy if the solution is inclusive or exclusive of xmin and xmax since i'll be using this over a large range of over 1000 or so. 如果解决方案是包容性的或不包括xmin和xmax,那就不过分挑剔,因为我将在超过1000左右的大范围内使用它。

Slice and create a mask with such min-max limits and thus select rows with boolean-indexing - 切片并创建具有此类最小 - 最大限制的掩码,从而选择具有boolean-indexing行 -

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

Sample runs - 样品运行 -

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. ]])

Without numpy , you could use bisect for this, to find insertion point. 没有numpy ,你可以使用bisect来找到插入点。 Note that the parameter is a list (I was adding None as second parameter as seen in here , but it's not useful). 请注意,参数是一个列表(我在这里添加None作为第二个参数,但它没有用)。

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))

result: 结果:

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

bisect requires that the list is sorted (which seems to be the case) or that won't work. bisect要求对列表进行排序(似乎是这种情况)或者不起作用。

Unordered 无序

If the given list of points are unordered, you can use a filter , and materialize with list : 如果给定的点列表是无序的,则可以使用filter ,并使用list

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

You can evidently feed your sorted list to this as well, but it will take considerably more time than the next approach. 您可以明显地将排序列表提供给此,但它将比下一个方法花费更多的时间。

Sorted list 排序列表

Given the points are sorted by x-coordinate , you can use the bisect package: 给定点按x坐标排序 ,您可以使用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]

Shouldn't simply 不应该简单

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

do the trick? 做诀窍? It's readable, fast and accessible. 它可读,快速且易于访问。

This list can be sorted or even pass an array, but the approach should be accessible enough to be changed to any needs. 此列表可以进行排序,甚至可以传递一个数组,但该方法应该足够可访问,以便根据需要进行更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM