我正在寻找最节省内存的方法来计算复杂numpy ndarray的绝对平方值
arr = np.empty((250000, 150), dtype='complex128') # common size
字符串
我还没有找到一个ufunc可以精确地执行np.abs()**2
。
由于这种大小和类型的数组占用大约半GB,我正在寻找一种主要是内存效率高的方法。
我也希望它是便携式的,所以理想的是一些ufuncs的组合。
到目前为止我的理解是这应该是最好的
result = np.abs(arr)
result **= 2
型
它将不必要地计算(**0.5)**2
,但应该就地计算**2
。总的来说,峰值内存需求仅为原始数组大小+结果数组大小,应为1.5 * 原始数组大小,因为结果是真实的。
如果我想摆脱无用的**2
调用,我必须这样做
result = arr.real**2
result += arr.imag**2
型
但如果我没弄错的话,这意味着我必须为**真实的和虚部计算分配内存,因此内存使用的峰值将是2.0 * 原始数组大小。arr.real
属性也返回一个非连续数组(但这不是那么重要)。
有什么我遗漏的吗?有更好的方法吗?
- 编辑1*:很抱歉没有说清楚,我不想覆盖它,所以我不能使用它作为输出。
6条答案
按热度按时间yvgpqqbh1#
感谢numba最新版本中的
numba.vectorize
,为任务创建一个numpy通用函数非常容易:字符串
在我的机器上,我发现与创建中间数组的纯numpy版本相比,速度提高了三倍:
型
nfs0ujit2#
编辑:这个解决方案有两倍的最低内存需求,只是稍微快一点。2评论中的讨论是很好的参考。
这里有一个更快的解决方案,结果存储在
res
中:字符串
其中我们利用了复数的绝对值的性质,即
abs(z) = sqrt(z*z.conjugate)
,因此abs(z)**2 = z*z.conjugate
wtlkbnrh3#
如果你的主要目标是节省内存,NumPy的ufuncs采用一个可选的
out
参数,让你将输出定向到你选择的数组。当你想就地执行操作时,它可能很有用。如果你对第一个方法做了这个小小的修改,那么你就可以在
arr
上完全执行操作了:字符串
一种只使用 * 一点点 * 额外内存的复杂方法是修改
arr
,计算新的真实的值数组,然后恢复arr
。这意味着存储符号的信息(除非你知道你的复数都有正的真实的和虚部)。每个真实的或虚值的符号只需要一个比特,所以这使用了
arr
的内存(除了你创建的新浮点数组)。型
以存储符号位为代价,
arr
保持不变,result
保持我们想要的值。gojuced74#
arr.real
和arr.imag
只是复杂数组的视图。因此没有分配额外的内存。t5zmwmid5#
如果你不想要
sqrt
(应该比乘法重得多),那么就不要abs
。如果你不想要双内存,那么没有
real**2 + imag**2
那么你可以试试这个(使用索引技巧)
字符串
无论如何,我更喜欢
numba
解决方案xqkwcwgp6#
如果你想计算一个复杂的numpy数组(即
abs()**2
)的平方大小,你可以使用numpy.abs()
函数来计算绝对值,然后使用numpy.square()
函数来计算平方值。下面是一个例子:字符串
这个例子演示了如何有效地计算一个复杂的numpy数组的平方大小。
np.abs()
函数被应用于逐元素计算绝对值,然后np.square()
被用于计算平方值。这种方法既简洁又节省内存。请记住,
np.abs()
函数返回一个实值数组,因此后续的np.square()
操作不涉及复数。如果您希望将结果保持为复数数组,则可以直接使用np.square(complex_array)
,因为对复数进行平方可以保留其复数性质。strong text