如何解决numpy:将数组的每个元素与所有其他元素±常数进行比较
我有一个长度为A
的一维Numpy数组N
。对于数组中的每个元素x
,我想知道数组中所有元素的比例在[x-eps
范围内; x+eps
],其中eps
是一个常数。 N
约为15,000。
目前,我的操作如下(最小示例):
import numpy as np
N = 15000
eps = 0.01
A = np.random.rand(N,1)
prop = np.array([np.mean((A >= x - eps) & (A <= x + eps)) for x in A])
..这在我的计算机上大约需要1秒钟。
我的问题:有没有更有效的方法?
编辑:我认为评论中的@jdehesa建议如下:
prop = np.isclose(A,A.T,atol=eps,rtol=0).mean(axis=1)
这是一个很好的简洁解决方案,但是(在我的计算机上)没有速度优势。
解决方法
这是利用np.searchsorted
-
sidx = A.argsort()
ridx = np.searchsorted(A,A+eps,'right',sorter=sidx)
lidx = np.searchsorted(A,A-eps,'left',sorter=sidx)
out = ridx - lidx
时间-
In [71]: N = 15000
...: eps = 0.01
...: A = np.random.rand(N)
In [72]: %timeit np.array([np.sum((A >= x - eps) & (A <= x + eps)) for x in A])
560 ms ± 5.15 ms per loop (mean ± std. dev. of 7 runs,1 loop each)
In [73]: %%timeit
...: sidx = A.argsort()
...: ridx = np.searchsorted(A,sorter=sidx)
...: lidx = np.searchsorted(A,sorter=sidx)
...: out = ridx - lidx
5.35 ms ± 47.9 µs per loop (mean ± std. dev. of 7 runs,100 loops each)
通过预分类的进一步改进:
In [81]: %%timeit
...: sidx = A.argsort()
...: b = A[sidx]
...: ridx = np.searchsorted(b,'right')
...: lidx = np.searchsorted(b,'left')
...: out = ridx - lidx
3.93 ms ± 19.9 µs per loop (mean ± std. dev. of 7 runs,100 loops each)
如评论中所述,对于等效的mean
版本,只需将最终数组输出除以N
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。