我有两个不同大小的numpy数组。其中一个“a”包含int值,而另一个(较大的)np数组“B”包含浮点值,其中每个元素/值有3-4个值。
a = np.random.randint(low = 1, high = 100, size = (7))
a
# array([35, 11, 48, 20, 13, 31, 49])
b = np.array([34.78, 34.8, 35.1, 34.99, 11.3, 10.7, 11.289, 18.78, 19.1, 20.05, 12.32, 12.87, 13.5, 31.03, 31.15, 29.87, 48.1, 48.5, 49.2])
a.shape, b.shape
# ((7,), (19,))
这个想法是找到“B”中的值与“a”中的每个唯一值在最近距离方面匹配,我使用abs值计算。要使用单个元素'a'或使用第一个元素'a'来执行此操作,请执行以下操作:
# Compare first element of a with all elements of b-
np.abs(a[0] - b).argsort()
'''
array([ 3, 2, 1, 0, 14, 13, 15, 16, 17, 18, 9, 8, 7, 12, 11, 10, 4,
6, 5])
'''
# b[3]
# 34.99
# np.abs(a[0] - b).argsort()[0]
# 3
b[np.abs(a[0] - b).argsort()[0]]
# 34.99
因此,“B”(B[3])中的第4个元素是与a[0]最接近的匹配。
为了计算'a'中的所有值,我使用一个循环:
for e in a:
idx = np.abs(e - b).argsort()
print(f"{e} has nearest match = {b[idx[0]]:.4f}")
'''
35 has nearest match = 34.9900
11 has nearest match = 11.2890
48 has nearest match = 48.1000
20 has nearest match = 20.0500
13 has nearest match = 12.8700
31 has nearest match = 31.0300
49 has nearest match = 49.2000
'''
如果没有slow for循环,我怎么能做到这一点呢?
注:a.shape = 1400和B.shape = 150万(近似值)
3条答案
按热度按时间yzxexxkh1#
如果你有很多值需要检查,你也可以尝试使用
kdTree
。对于很少的值,构建树的开销不会使其值得,但是对于大n,特别是在多维空间中搜索最近邻,它比计算所有对的距离要快得多:ekqde3dh2#
让我们来分解一下:
a[:, None] - b[None, :]
在两个不同的方向上扩展a
和b
。这使得a
的所有元素与b
的所有元素不同,并将它们存储到大小为len(a) * len(b)
的2D数组中。这是替换for
循环的部分np.argmin(..., axis=1)
为每行选择最小值。每个值都以range(0, len(b))
为单位b[...]
然后选择值rur96b6h3#
你可以使用广播来计算所有对的绝对差,
numpy.argmin
来获得每行最小值的索引(具有O(n)
复杂度,而排序是O(n*logn)
):输出:
array([34.99 , 11.289, 48.1 , 20.05 , 12.87 , 31.03 , 49.2 ])
要知道,两个数组的所有组合都将被一次性计算,中间数组的大小为
len(a) * len(b)
,请确保您有足够的内存,因为a
和b
都很大。中间值
abs(a[:,None]-b)
(为了更好的显示,四舍五入到小数点后1位)。行对应于a
的元素,列对应于b
的元素:用于索引
b
的中间体np.argmin(abs(a[:,None]-b), axis=1)
: