我正在执行大量这些计算:
A == A [np.newaxis] .T
其中A是一个密集的numpy数组,通常具有共同的值.
出于基准测试目的,我们可以使用:
n = 30000 A = np.random.randint(0,1000,n) A == A[np.newaxis].T
当我执行此计算时,我遇到了内存问题.我相信这是因为输出不是更高效的bitarray或np.packedbits格式.第二个问题是我们正在进行两次必要的比较,因为得到的布尔数组是对称的.
我的问题是:
>是否有可能以更高内存效率的方式生成布尔numpy数组输出而不牺牲速度?我所知道的选项是bitarray和np.packedbits,但我只知道在创建大型布尔数组后如何应用这些选项.
>我们能否利用计算的对称性将处理的比较数量减半,同样不会牺牲速度?
我需要能够表演&和|对布尔数组输出的操作.我尝试过bitarray,这对于这些按位操作非常快.但包装np.ndarray的速度很慢 – > bitarray然后解压缩bitarray – > np.ndarray.
[编辑提供澄清.]
解决方法
这里有一个numba给我们一个NumPy布尔数组作为输出 –
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,out) out.ravel()[::out.shape[1]+1] = 1 return out
计时 –
In [287]: np.random.seed(0) ...: n = 30000 ...: A = np.random.randint(0,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