我想对你的问题提出两个解决办法。第一个是纯numpy解决方案,但是如果原始数组是NxM,序列大小是K,那么它将使用NxMxK大小的数组。所以这个解决方案只有在你的情况下这个尺寸不是很大的时候才是好的。尽管使用了很大的阵列,但它仍然可以非常快地完成在numpy空间中的所有工作。在
第二种方法是使用@np.vectorize的混合方法(代码也变得更简单)。它在numpy空间中执行循环,但为每个元素调用python。好处是它避免了创建巨大的数组。在
两者都是有效的解决办法。您可以选择一个与您的阵列大小最匹配的。在
而且,这两种方法都可以处理任意维的数组。在
解决方案1import numpy as np
a = np.random.random((2,4))
a
=>
array([[ 0.5501662 , 0.13055979, 0.579619 , 0.3161156 ],
[ 0.07327783, 0.45156743, 0.38334009, 0.48772392]])
seq = np.array([ 0.1, 0.3, 0.6, 0.63 ])
# create 3-dim array of all the distances
all_dists = np.abs(a[..., np.newaxis] - seq)
all_dists.shape
=> (2, 4, 4)
all_dists
=>
array([[[ 0.4501662 , 0.2501662 , 0.0498338 , 0.0798338 ],
[ 0.03055979, 0.16944021, 0.46944021, 0.49944021],
[ 0.479619 , 0.279619 , 0.020381 , 0.050381 ],
[ 0.2161156 , 0.0161156 , 0.2838844 , 0.3138844 ]],
[[ 0.02672217, 0.22672217, 0.52672217, 0.55672217],
[ 0.35156743, 0.15156743, 0.14843257, 0.17843257],
[ 0.28334009, 0.08334009, 0.21665991, 0.24665991],
[ 0.38772392, 0.18772392, 0.11227608, 0.14227608]]])
# find where each element gets its closest, i.e. min dist
closest_idxs = all_dists.argmin(axis = -1)
closest_idxs
=>
array([[2, 0, 2, 1],
[0, 2, 1, 2]])
# choose
seq[closest_idxs]
=>
array([[ 0.6, 0.1, 0.6, 0.3],
[ 0.1, 0.6, 0.3, 0.6]])
解决方案2
^{pr2}$