从已排序的 Numpy 数组中移除最少数量的元素,以便剩余元素之间的最小距离始终大于某个阈值的最佳方法是什么?
例如,如果阈值为1
,则以下序列[0.1, 0.5, 1.1, 2.5, 3.]
将变为[0.1, 1.1 , 2.5]
。 0.5
被移除,因为它离 0.1
太近了,但是 1.1
被保留了下来,因为它离 0.1
足够远>.
我当前的代码:
import numpy as np
MIN_DISTANCE = 1
a = np.array([0.1, 0.5, 1.1, 2.5, 3.])
for i in range(len(a)-1):
if(a[i+1] - a[i] < MIN_DISTANCE):
a[i+1] = a[i]
a = np.unique(a)
a
array([0.1, 1.1, 2.5])
有没有更有效的方法?
请注意,我的问题类似于 Remove values from numpy array closer to each other但不完全一样。
最佳答案
你可以使用 numpy.ufunc.accumulate遍历数组的相邻对而不是 for
循环。
numpy.add.accumulate
示例或 itertools.accumulate可能最好地展示了它在做什么。- 连同 numpy.frompyfunc您的条件可以应用为
ufunc
( universal functions )。
代码:(使用扩展数组来交叉检查一些其他情况,但也适用于您的数组)
import numpy as np
MIN_DISTANCE = 1
a = np.array([0.1, 0.5, 0.6, 0.7, 1.1, 2.5, 3., 4., 6., 6.1])
print("original: \n" + str(a))
def my_py_function(arr1, arr2):
if(arr2 - arr1 < MIN_DISTANCE):
arr2 = arr1
return arr2
my_np_function = np.frompyfunc(my_py_function, 2, 1)
my_np_function.accumulate(a, dtype=np.object, out=a).astype(float)
print("complete: \n" + str(a))
a = np.unique(a)
print("unique: \n" + str(a))
结果:
original:
[0.1 0.5 0.6 0.7 1.1 2.5 3. 4. 6. 6.1]
complete:
[0.1 0.1 0.1 0.1 1.1 2.5 2.5 4. 6. 6. ]
unique:
[0.1 1.1 2.5 4. 6. ]
关于执行时间timeit显示阵列长度约为 20 时的转变。
- 对于长度为 5 的数组,您的代码要快得多(相对)
- 而对于数组长度 >>20,accumulate 选项会大大加快速度(数组长度为 300 的时间约为 35%)
关于从接近阈值的 Numpy 数组中删除元素的 Pythonic 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57327908/