繁体   English   中英

Numpy:将数组的每个元素与所有其他元素进行比较(± 常数)

[英]Numpy: compare each element of array with all other elements (± constant)

我有一个长度为N一维 Numpy 数组A 对于数组中的每个元素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, A+eps, 'right', sorter=sidx)
    ...: lidx = np.searchsorted(A, A-eps, 'left', 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, A+eps, 'right')
    ...: lidx = np.searchsorted(b, A-eps, 'left')
    ...: out = ridx - lidx
3.93 ms ± 19.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

如评论中所述,对于mean等效版本,只需将最终数组输出除以N

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM