具有负值的大型矩阵的平方根计算的内存高效方法

时间:2019-05-04 09:10:09

标签: python performance numpy sqrt

我需要计算带有正负数的大型矩阵的sqrt。问题是因为s​​qrt对符号敏感。所以我正在使用以下代码。

neg=numpy.argwhere(temp<0)
temp=numpy.abs(temp)
temp=numpy.sqrt(temp)
temp[neg]=-temp[neg]

在这段代码中,我首先存储负值的位置,然后在转换为正数之后计算平方根,然后在其上附加负号。问题在于它在第一条语句中给出了内存错误。

是否有替代内存和高效计算的方法来实现相同任务。矩阵的大小约为O(10^5)

2 个答案:

答案 0 :(得分:3)

在处理大数据时,如果预期的操作可以表示为算术运算,我们也可以使用支持多核处理的numexpr module。需要注意的是,我们需要使用算术矢量化运算。因此,针对我们问题的算术解决方案是-

(2*(temp>=0)-1)*np.sqrt(np.abs(temp))

将其移植到numexpr很简单-

import numexpr as ne

ne.evaluate('(2*(temp>=0)-1)*sqrt(abs(temp))')

基准化

原始功能-

def orgfunc(temp):
    neg=temp<0
    temp=numpy.abs(temp)
    temp=numpy.sqrt(temp)
    temp[neg]=-temp[neg]
    return temp

大型数组上的计时-

In [55]: np.random.seed(0)
    ...: m,n = 1000,1000
    ...: temp = np.random.randn(m,n)

In [56]: %timeit orgfunc(temp)
100 loops, best of 3: 16 ms per loop

In [57]: %timeit ne.evaluate('(2*(temp>=0)-1)*sqrt(abs(temp))')
100 loops, best of 3: 2.47 ms per loop

In [58]: np.random.seed(0)
    ...: m,n = 10000,10000
    ...: temp = np.random.randn(m,n)

In [59]: %timeit orgfunc(temp)
1 loop, best of 3: 2.09 s per loop

In [60]: %timeit ne.evaluate('(2*(temp>=0)-1)*sqrt(abs(temp))')
1 loop, best of 3: 248 ms per loop

答案 1 :(得分:0)

Numpy“ where”是适合您的问题的替代方法,请尝试以下代码:

result = numpy.where(a>=0, numpy.sqrt(a), -numpy.sqrt(-a))

如果正数或零,此代码行返回矩阵中数字的平方根;否则,负数平方根返回负数。