python - 有效地按元素比较numpy数组与自身

标签 python numpy

我正在执行大量这些计算:

A == A[np.newaxis].T

其中 A 是一个密集的 numpy 数组,它通常具有共同的值。

为了进行基准测试,我们可以使用:

n = 30000
A = np.random.randint(0, 1000, n)
A == A[np.newaxis].T

当我执行此计算时,我遇到了内存问题。我相信这是因为输出不是更有效的位数组或 np.packedbits 格式。次要问题是我们执行的比较次数是必要次数的两倍,因为生成的 bool 数组是对称的。

我的问题是:

  1. 是否可以在不牺牲速度的情况下以更节省内存的方式生成 bool numpy 数组输出?我知道的选项是 bitarray 和 np.packedbits,但我只知道如何在创建大型 bool 数组后应用它们。
  2. 我们能否利用计算的对称性将处理的比较次数减半,同时又不牺牲速度?

我需要能够执行 & 和 |对 bool 数组输出的操作。我已经尝试过 bitarray,它对于这些按位运算来说是超快的。但是打包 np.ndarray -> bitarray 然后解压 bitarray -> np.ndarray 很慢。

[编辑以提供澄清。]

最佳答案

这是一个带有 numba 的代码,它给我们一个 NumPy bool 数组作为输出 -

from numba import njit

@njit
def numba_app1(idx, n, s, out):
    for i,j in zip(idx[:-1],idx[1:]):
        s0 = s[i:j]
        c = 0
        for p1 in s0[c:]:
            for p2 in s0[c+1:]:
                out[p1,p2] = 1
                out[p2,p1] = 1
            c += 1
    return out

def app1(A):
    s = A.argsort()
    b = A[s]
    n = len(A)
    idx = np.flatnonzero(np.r_[True,b[1:] != b[:-1],True])
    out = np.zeros((n,n),dtype=bool)
    numba_app1(idx, n, s, out)
    out.ravel()[::out.shape[1]+1] = 1
    return out

时间 -

In [287]: np.random.seed(0)
     ...: n = 30000
     ...: A = np.random.randint(0, 1000, n)

# Original soln
In [288]: %timeit A == A[np.newaxis].T
1 loop, best of 3: 317 ms per loop

# @Daniel F's soln-1 that skips assigning lower diagonal in output
In [289]: %timeit sparse_outer_eq(A)
1 loop, best of 3: 450 ms per loop

# @Daniel F's soln-2 (complete one)
In [291]: %timeit sparse_outer_eq(A)
1 loop, best of 3: 634 ms per loop

# Solution from this post
In [292]: %timeit app1(A)
10 loops, best of 3: 66.9 ms per loop

关于python - 有效地按元素比较numpy数组与自身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48279206/

相关文章:

python - 如何将列表列表中的每个元素除以python中的数字

python - 在 SymPy 中使用 Lambdify 消除公共(public)子表达式的最佳实践

python - 根据条件创建列

python - 如何查看用OpenCV生成的图像的金字塔?

Python正则表达式查找大括号的所有情况,包括括号

python - 根据缺失时间范围自动填充数据库中缺失的行

python - 为什么 Python 中的命名表达式需要专用语法(:=, 海象运算符)?

python - 更改具有重复列标题的数据框列中的数据类型

python - 在 NumPy 数组中搜索序列

python - 如何将此代码从 matlab 转换为 python?