[英]Finding similar entries in python lists
我有 2 个元组列表list1 = [(1.332, 3.23344, 3.22), (2.122, 2.11, 2.33), ... (1, 2, 3)]
和list2 = [(4.23, 12.2, 3.333), (1.234, 3.21, 4.342), ... (1.1, 2.2, 3.3)]
。 这些列表都很长,两个列表都有数百万。 就上下文而言,这些数据点中的每一个都是 position 在两个不同数据集中的某种度量。 现在我想将list1
中的每个条目对应到list2
中的一个条目,如果它“足够接近”的话。 足够接近是指位置之间的距离小于某个阈值(例如 1)。 我最初的想法是在list1
的每个条目上使用min
function 。 也就是说,以下内容:
import numpy as np
import random
def dist(pt1, pt2):
return np.sqrt( ((pt2[0] - pt1[0]) ** 2) + ((pt2[1] - pt1[1]) ** 2) + ((pt2[2] - pt1[2]) ** 2) )
list1 = [(random.random(), random.random(), random.random()) for _ in range(25)]
list2 = [(random.random(), random.random(), random.random()) for _ in range(20)]
threshold = .5
linker = []
for i, entry in enumerate(list1):
m = min(list2, key=lambda x: dist(entry, x))
if dist(entry, m) < threshold:
linker.append((i, list2.index(m))
因此,这会将list1
中的每个索引链接到list2
中的索引。 但我觉得必须有一些专门针对这个任务开发的算法,它要快得多,是吗?
您正在查找数据集中每个点与第二个数据集的最近邻。
对于大型数据集, 最近邻方法要好得多,因为它们的复杂度为 O(N*log(N))
Python 中两个流行的是KDTree 和 BallTree
用 BallTree 解决这个问题的一个例子
import numpy as np
from sklearn.neighbors import BallTree
# Generate Dataset 1 (random positions in 3D)
rng = np.random.RandomState(0)
X = rng.random_sample((10, 3)) # 10 points in 3 dimensions
# Setup nearest neighbor tree for dataset 1
# to process nearest neighbor queries
tree = BallTree(X, leaf_size=2)
# Generate Dataset 2 (random positions in 3D)
Y = rng.random_sample((10, 3))
# For each point in Dataset 2
# find the index and distance to the closest
# point in Dataset 1 (using the nearest neighbor tree
# for dataset 1)
dist, ind = tree.query(Y, k=1) # nearest neighbor
# Results
for i, (ind, d) in enumerate(zip(ind, dist)):
print(f'Y index {i}, closest index X is {ind}, dist {d}')
Output
Y index 0, closest index X is [3], dist [0.14046915]
Y index 1, closest index X is [1], dist [0.40653272]
Y index 2, closest index X is [7], dist [0.29291477]
Y index 3, closest index X is [1], dist [0.25785655]
Y index 4, closest index X is [1], dist [0.39477652]
Y index 5, closest index X is [9], dist [0.50373484]
Y index 6, closest index X is [1], dist [0.24894356]
Y index 7, closest index X is [4], dist [0.14716665]
Y index 8, closest index X is [5], dist [0.25875381]
Y index 9, closest index X is [8], dist [0.24204497]
是的,绝对这是一种耗时的方法,因为首先 python 没有针对这些计算进行优化(针对数据类型等),其次这些计算需要在任何语言中进行优化。 您必须使用库来操作矩阵,例如 numpy 和 pandas。 for example in your case i recommend this solution: first: convert your data to a dataframe of pandas like this post: List of Tuples to DataFrame Conversion second: after that conversion with pandas this is a routin and easy calculation. 例如: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.pow.ZFC35FDC70D5FC69D2698Z83A822C7A5E3
pandas 使用 numpy 和 numpy 针对这些计算进行了优化。
一个简单的解决方案是保留一个 3d 单元格数组,以将您的条目分组。 例如, (1.332, 3.23344, 3.22)
可能被分组到单元格(13, 32, 32)
中。 打包该数据结构后,您可以通过查看(13, 32, 32)
(及其 26 个邻居的某个子集)找到(1.332, 3.23344, 3.22)
附近的所有点。
如果你真的需要这个速度很快,你就会进入一组称为“空间分区器”的算法。 您可能会研究一种称为“kd-tree”的东西,它非常适合以超紧凑的方式存储点的非均匀分布(并且针对检索某个位置的邻域中的点进行了优化。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.