在公差范围内查找 Python 中两个矩阵的交集?
Finding intersection of two matrices in Python within a tolerance?
我正在寻找找到两个不同大小矩阵的交集的最有效方法。每个矩阵都有三个变量(列)和不同数量的观察值(行)。例如矩阵A:
a = np.matrix('1 5 1003; 2 4 1002; 4 3 1008; 8 1 2005')
b = np.matrix('7 9 1006; 4 4 1007; 7 7 1050; 8 2 2003'; 9 9 3000; 7 7 1000')
如果我将每列的公差设置为 col1 = 1
、col2 = 2
和 col3 = 10
,我需要一个函数,以便它输出 [=16= 中的索引] 和 b
在各自的公差范围内,例如:
[x1, x2] = func(a, b, col1, col2, col3)
print x1
>> [2 3]
print x2
>> [1 3]
您可以通过索引看到,a
的元素 2 在 b
的元素 1 的公差范围内。
我想我可以遍历矩阵 a
的每个元素,检查它是否在 b
中每个元素的容差范围内,然后这样做。但是对于非常大的数据集来说似乎效率低下。
对于完成此操作的循环方法的替代方法有什么建议吗?
如果您不介意使用 NumPy 数组,您可以利用 broadcasting
获得矢量化解决方案。这是实现 -
# Set tolerance values for each column
tol = [1, 2, 10]
# Get absolute differences between a and b keeping their columns aligned
diffs = np.abs(np.asarray(a[:,None]) - np.asarray(b))
# Compare each row with the triplet from `tol`.
# Get mask of all matching rows and finally get the matching indices
x1,x2 = np.nonzero((diffs < tol).all(2))
样本运行-
In [46]: # Inputs
...: a=np.matrix('1 5 1003; 2 4 1002; 4 3 1008; 8 1 2005')
...: b=np.matrix('7 9 1006; 4 4 1007; 7 7 1050; 8 2 2003; 9 9 3000; 7 7 1000')
...:
In [47]: # Set tolerance values for each column
...: tol = [1, 2, 10]
...:
...: # Get absolute differences between a and b keeping their columns aligned
...: diffs = np.abs(np.asarray(a[:,None]) - np.asarray(b))
...:
...: # Compare each row with the triplet from `tol`.
...: # Get mask of all matching rows and finally get the matching indices
...: x1,x2 = np.nonzero((diffs < tol).all(2))
...:
In [48]: x1,x2
Out[48]: (array([2, 3]), array([1, 3]))
大数据大小情况:如果您正在处理导致内存问题的大数据大小,并且由于您已经知道列数是一个小数字3
,您可能希望有一个最小的 3
迭代循环并节省大量内存占用,就像这样 -
na = a.shape[0]
nb = b.shape[0]
accum = np.ones((na,nb),dtype=bool)
for i in range(a.shape[1]):
accum &= np.abs((a[:,i] - b[:,i].ravel())) < tol[i]
x1,x2 = np.nonzero(accum)
我正在寻找找到两个不同大小矩阵的交集的最有效方法。每个矩阵都有三个变量(列)和不同数量的观察值(行)。例如矩阵A:
a = np.matrix('1 5 1003; 2 4 1002; 4 3 1008; 8 1 2005')
b = np.matrix('7 9 1006; 4 4 1007; 7 7 1050; 8 2 2003'; 9 9 3000; 7 7 1000')
如果我将每列的公差设置为 col1 = 1
、col2 = 2
和 col3 = 10
,我需要一个函数,以便它输出 [=16= 中的索引] 和 b
在各自的公差范围内,例如:
[x1, x2] = func(a, b, col1, col2, col3)
print x1
>> [2 3]
print x2
>> [1 3]
您可以通过索引看到,a
的元素 2 在 b
的元素 1 的公差范围内。
我想我可以遍历矩阵 a
的每个元素,检查它是否在 b
中每个元素的容差范围内,然后这样做。但是对于非常大的数据集来说似乎效率低下。
对于完成此操作的循环方法的替代方法有什么建议吗?
如果您不介意使用 NumPy 数组,您可以利用 broadcasting
获得矢量化解决方案。这是实现 -
# Set tolerance values for each column
tol = [1, 2, 10]
# Get absolute differences between a and b keeping their columns aligned
diffs = np.abs(np.asarray(a[:,None]) - np.asarray(b))
# Compare each row with the triplet from `tol`.
# Get mask of all matching rows and finally get the matching indices
x1,x2 = np.nonzero((diffs < tol).all(2))
样本运行-
In [46]: # Inputs
...: a=np.matrix('1 5 1003; 2 4 1002; 4 3 1008; 8 1 2005')
...: b=np.matrix('7 9 1006; 4 4 1007; 7 7 1050; 8 2 2003; 9 9 3000; 7 7 1000')
...:
In [47]: # Set tolerance values for each column
...: tol = [1, 2, 10]
...:
...: # Get absolute differences between a and b keeping their columns aligned
...: diffs = np.abs(np.asarray(a[:,None]) - np.asarray(b))
...:
...: # Compare each row with the triplet from `tol`.
...: # Get mask of all matching rows and finally get the matching indices
...: x1,x2 = np.nonzero((diffs < tol).all(2))
...:
In [48]: x1,x2
Out[48]: (array([2, 3]), array([1, 3]))
大数据大小情况:如果您正在处理导致内存问题的大数据大小,并且由于您已经知道列数是一个小数字3
,您可能希望有一个最小的 3
迭代循环并节省大量内存占用,就像这样 -
na = a.shape[0]
nb = b.shape[0]
accum = np.ones((na,nb),dtype=bool)
for i in range(a.shape[1]):
accum &= np.abs((a[:,i] - b[:,i].ravel())) < tol[i]
x1,x2 = np.nonzero(accum)