我在算法中使用了许多大型多维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
的所有变量都将指向已更改的数据。
答案 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
由于这是在视图上完成的,如果你查看原始的A
和A_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
...指针切换