如果 2 点之间的距离低于某个阈值,则从列表中删除点
Removing points from list if distance between 2 points is below a certain threshold
我有一个点列表,我想仅当点之间的距离大于某个阈值时才保留列表中的点。因此,从第一个点开始,如果第一个点和第二个点之间的距离小于阈值,那么我将删除第二个点,然后计算第一个点和第三个点之间的距离。如果这个距离小于阈值,比较第一点和第四点。否则移动到第三和第四之间的距离等等。
例如,如果阈值是 2 并且我有
list = [1, 2, 5, 6, 10]
那么我希望
new_list = [1, 5, 10]
谢谢!
不是花哨的单行代码,但您可以使用 [-1]
迭代列表中的值,如果当前值大于新列表中的最后一个值,则将它们追加到某个新列表中:
lst = range(10)
diff = 3
new = []
for n in lst:
if not new or abs(n - new[-1]) >= diff:
new.append(n)
之后,new
就是[0, 3, 6, 9]
。
关于您的评论 "What if i had instead a list of coordinates (x,y)?":在这种情况下,您做的事情完全相同,只是您必须找到两点之间的 Euclidean distance,而不是仅仅比较数字。因此,假设 lst
是 (x,y)
对的列表:
if not new or ((n[0]-new[-1][0])**2 + (n[1]-new[-1][1])**2)**.5 >= diff:
或者,您可以将 (x,y)
对转换为 complex
数字。对于那些,加减法和绝对值等基本操作已经定义,所以你可以再次使用上面的代码。
lst = [complex(x,y) for x,y in lst]
new = []
for n in lst:
if not new or abs(n - new[-1]) >= diff: # same as in the first version
new.append(n)
print(new)
现在,new
是表示点的复数列表:[0j, (3+3j), (6+6j), (9+9j)]
虽然 tobias_k 的解决方案有效,但它不是最有效的(在我看来,但我可能忽略了一些东西)。它基于列表顺序,不考虑在解决方案中最后淘汰接近(在阈值内)其他元素最大数量的元素。应首先考虑和检查具有最少此类连接(或邻近度)的元素。我建议的方法可能允许保留给定列表中其他元素的指定阈值之外的最大点数。这对于向量列表以及 x,y 或 x,y,z 坐标非常有效。但是,如果您打算将此解决方案与标量列表一起使用,则只需将此行包含在代码中 orig_list=np.array(orig_list)[:,np.newaxis].tolist()
请看下面的解决方法:
import numpy as np
thresh = 2.0
orig_list=[[1,2], [5,6], ...]
nsamp = len(orig_list)
arr_matrix = np.array(orig_list)
distance_matrix = np.zeros([nsamp, nsamp], dtype=np.float)
for ii in range(nsamp):
distance_matrix[:, ii] = np.apply_along_axis(lambda x: np.linalg.norm(np.array(x)-np.array(arr_matrix[ii, :])),
1,
arr_matrix)
n_proxim = np.apply_along_axis(lambda x: np.count_nonzero(x < thresh),
0,
distance_matrix)
idx = np.argsort(n_proxim).tolist()
idx_out = list()
for ii in idx:
for jj in range(ii+1):
if ii not in idx_out:
if self.distance_matrix[ii, jj] < thresh:
if ii != jj:
idx_out.append(jj)
pop_idx = sorted(np.unique(idx_out).tolist(),
reverse=True)
for pop_id in pop_idx:
orig_list.pop(pop_id)
nsamp = len(orig_list)
我有一个点列表,我想仅当点之间的距离大于某个阈值时才保留列表中的点。因此,从第一个点开始,如果第一个点和第二个点之间的距离小于阈值,那么我将删除第二个点,然后计算第一个点和第三个点之间的距离。如果这个距离小于阈值,比较第一点和第四点。否则移动到第三和第四之间的距离等等。
例如,如果阈值是 2 并且我有
list = [1, 2, 5, 6, 10]
那么我希望
new_list = [1, 5, 10]
谢谢!
不是花哨的单行代码,但您可以使用 [-1]
迭代列表中的值,如果当前值大于新列表中的最后一个值,则将它们追加到某个新列表中:
lst = range(10)
diff = 3
new = []
for n in lst:
if not new or abs(n - new[-1]) >= diff:
new.append(n)
之后,new
就是[0, 3, 6, 9]
。
关于您的评论 "What if i had instead a list of coordinates (x,y)?":在这种情况下,您做的事情完全相同,只是您必须找到两点之间的 Euclidean distance,而不是仅仅比较数字。因此,假设 lst
是 (x,y)
对的列表:
if not new or ((n[0]-new[-1][0])**2 + (n[1]-new[-1][1])**2)**.5 >= diff:
或者,您可以将 (x,y)
对转换为 complex
数字。对于那些,加减法和绝对值等基本操作已经定义,所以你可以再次使用上面的代码。
lst = [complex(x,y) for x,y in lst]
new = []
for n in lst:
if not new or abs(n - new[-1]) >= diff: # same as in the first version
new.append(n)
print(new)
现在,new
是表示点的复数列表:[0j, (3+3j), (6+6j), (9+9j)]
虽然 tobias_k 的解决方案有效,但它不是最有效的(在我看来,但我可能忽略了一些东西)。它基于列表顺序,不考虑在解决方案中最后淘汰接近(在阈值内)其他元素最大数量的元素。应首先考虑和检查具有最少此类连接(或邻近度)的元素。我建议的方法可能允许保留给定列表中其他元素的指定阈值之外的最大点数。这对于向量列表以及 x,y 或 x,y,z 坐标非常有效。但是,如果您打算将此解决方案与标量列表一起使用,则只需将此行包含在代码中 orig_list=np.array(orig_list)[:,np.newaxis].tolist()
请看下面的解决方法:
import numpy as np
thresh = 2.0
orig_list=[[1,2], [5,6], ...]
nsamp = len(orig_list)
arr_matrix = np.array(orig_list)
distance_matrix = np.zeros([nsamp, nsamp], dtype=np.float)
for ii in range(nsamp):
distance_matrix[:, ii] = np.apply_along_axis(lambda x: np.linalg.norm(np.array(x)-np.array(arr_matrix[ii, :])),
1,
arr_matrix)
n_proxim = np.apply_along_axis(lambda x: np.count_nonzero(x < thresh),
0,
distance_matrix)
idx = np.argsort(n_proxim).tolist()
idx_out = list()
for ii in idx:
for jj in range(ii+1):
if ii not in idx_out:
if self.distance_matrix[ii, jj] < thresh:
if ii != jj:
idx_out.append(jj)
pop_idx = sorted(np.unique(idx_out).tolist(),
reverse=True)
for pop_id in pop_idx:
orig_list.pop(pop_id)
nsamp = len(orig_list)