在NumPy中交换数组数据

时间:2012-03-31 08:45:45

标签: python arrays numpy swap

我在算法中使用了许多大型多维NP阵列(2D和3D)。这里有许多迭代,并且在每次迭代期间,通过执行计算并保存到相同大小的临时数组中来重新计算数组。在单次迭代结束时,临时数组的内容将被复制到实际的数据数组中。

示例:

global A, B # ndarrays
A_temp = numpy.zeros(A.shape)
B_temp = numpy.zeros(B.shape)
for i in xrange(num_iters):
    # Calculate new values from A and B storing in A_temp and B_temp...
    # Then copy values from temps to A and B
    A[:] = A_temp
    B[:] = B_temp

这很好用,但是当A和B只能交换时复制所有这些值似乎有点浪费。以下内容将交换数组:

A, A_temp = A_temp, A
B, B_temp = B_temp, B

但是在其他范围内可以有其他引用的引用,这些引用不会改变。

似乎NumPy可以有一个内部方法来交换两个数组的内部数据指针,例如numpy.swap(A, A_temp)。然后,指向A的所有变量都将指向已更改的数据。

3 个答案:

答案 0 :(得分:1)

也许你可以通过添加一个间接级别来解决这个问题。

你可以拥有一个“数组持有者”类。所有这一切都是保持对底层NumPy数组的引用。为这两者实施廉价的掉期操作将是微不足道的。

如果所有外部引用都是这些持有者对象而不是直接引用到数组,那么这些引用都不会被交换无效。

答案 1 :(得分:1)

我意识到这是一个老问题,但是对于它的价值,您还可以通过执行xor交换在两个ndarray缓冲区(没有临时副本)之间交换数据:

A_bytes = A.view('ubyte')
A_temp_bytes = A.view('ubyte')
A_bytes ^= A_temp_bytes
A_temp_bytes ^= A_bytes
A_bytes ^= A_temp_bytes

由于这是在视图上完成的,如果你查看原始的AA_temp数组(无论它们的原始dtype是什么),它们的值应该正确交换。这基本上等同于您所寻找的numpy.swap(A, A_temp)。不幸的是,它需要3个循环 - 如果它被实现为ufunc(也许它应该是),它会快得多。

答案 2 :(得分:0)

即使你的方式应该工作得很好(我怀疑问题出在其他地方),你可以尝试明确地做:

import numpy as np
A, A_temp = np.frombuffer(A_temp), np.frombuffer(A)

验证您的方法是否也能正常运行并不难:

>>> import numpy as np
>>> arr = np.zeros(100)
>>> arr2 = np.ones(100)
>>> print arr.__array_interface__['data'][0], arr2.__array_interface__['data'][0]
152523144 152228040

>>> arr, arr2 = arr2, arr
>>> print arr.__array_interface__['data'][0], arr2.__array_interface__['data'][0]
152228040 152523144

...指针切换