我不熟悉 XOR 运算,我想知道是否有一种有效的方法通过节省内存使用来对两个 2D NumPy 数组之间的每个元素执行 XOR 运算。
这是我的玩具示例:
# Example arrays
u_values = np.array([[True, True, True, True, True, True, False, True, True, True],
[True, True, True, True, True, True, True, False, False, True],
[True, True, True, True, False, True, False, True, True, True],
[True, True, True, True, False, True, True, False, False, True],
[True, True, True, True, True, False, False, False, False, True],
[True, True, True, False, False, False, False, False, False, True],
[True, False, False, False, False, False, False, False, False, True],
[True, True, False, True, False, True, False, True, True, True]])
v_values = np.array([[True, True, True, True, True, True, False, True, True, True],
[True, False, True, False, True, True, True, False, False, True],
[True, True, True, True, False, True, False, True, True, True],
[True, False, True, True, False, False, True, False, False, True],
[True, True, False, True, True, False, False, False, False, True],
[True, True, True, False, False, True, False, False, False, True]])
这是我尝试过的:
u_reshaped = u_values[:, None, :]
v_reshaped = v_values[None, :, :]
xor_result = u_reshaped ^ v_reshaped
xor_results = xor_result.reshape((-1, xor_result.shape[2]))
我什至尝试使用 np.packbits 来看看是否可以节省内存:
u_values_packed = np.packbits(u_values, axis=1)
v_values_packed = np.packbits(v_values, axis=1)
result_packed = u_values_packed[:, None, :] ^ v_values_packed[None, :, :]
result_packed = result_packed.reshape((-1, result_packed.shape[2]))
result_unpacked = np.unpackbits(result_packed, axis=1)[:, :u_values.shape[1]]
当我执行实际用例时,我收到此错误:
numpy.core._exceptions.MemoryError: Unable to allocate 959. GiB for an array with shape (2788, 1813, 203769) and data type uint8
如何使用更少的内存来实现这一目标?
为了澄清问题,这是我对尺寸为 (48,10) 的玩具示例的预期输出:
[[False False False False False False False False False False]
[False True False True False False True True True False]
[False False False False True False False False False False]
[False True False False True True True True True False]
[False False True False False True False True True False]
[False False False True True False False True True False]
[False False False False False False True True True False]
[False True False True False False False False False False]
[False False False False True False True True True False]
[False True False False True True False False False False]
[False False True False False True True False False False]
[False False False True True False True False False False]
[False False False False True False False False False False]
[False True False True True False True True True False]
[False False False False False False False False False False]
[False True False False False True True True True False]
[False False True False True True False True True False]
[False False False True False False False True True False]
[False False False False True False True True True False]
[False True False True True False False False False False]
[False False False False False False True True True False]
[False True False False False True False False False False]
[False False True False True True True False False False]
[False False False True False False True False False False]
[False False False False False True False True True False]
[False True False True False True True False False False]
[False False False False True True False True True False]
[False True False False True False True False False False]
[False False True False False False False False False False]
[False False False True True True False False False False]
[False False False True True True False True True False]
[False True False False True True True False False False]
[False False False True False True False True True False]
[False True False True False False True False False False]
[False False True True True False False False False False]
[False False False False False True False False False False]
[False True True True True True False True True False]
[False False True False True True True False False False]
[False True True True False True False True True False]
[False False True True False False True False False False]
[False True False True True False False False False False]
[False True True False False True False False False False]
[False False True False True False False False False False]
[False True True True True False True True True False]
[False False True False False False False False False False]
[False True True False False True True True True False]
[False False False False True True False True True False]
[False False True True False False False True True False]]
通过使用 numpy.bitwise_xor 函数并按块迭代数组,可以在两个 2D NumPy 数组的每个元素之间执行 XOR,同时有效管理内存。这有助于避免一次将整个数组加载到内存中,尤其是对于大型数组。以下是如何执行此操作的示例:
import numpy as np
def xor_arrays_efficiently(arr1, arr2, chunk_size=1000):
rows, cols = arr1.shape
result = np.empty((rows, cols), dtype=arr1.dtype)
for i in range(0, rows, chunk_size):
chunk_end = min(i + chunk_size, rows)
# Load a chunk of rows from both arrays
chunk_arr1 = arr1[i:chunk_end, :]
chunk_arr2 = arr2[i:chunk_end, :]
# Perform XOR on the chunk
result[i:chunk_end, :] = np.bitwise_xor(chunk_arr1, chunk_arr2)
return result
# Example usage
array1 = np.array([[1, 0, 1], [0, 1, 0], [1, 1, 0]])
array2 = np.array([[0, 1, 1], [1, 0, 0], [1, 1, 1]])
result = xor_arrays_efficiently(array1, array2)
print(result)
在此示例中,chunk_size 参数确定一次处理多少行。您可能需要根据可用内存和数组大小调整此值。这种方法可以通过处理数组块而不是立即将整个数组加载到内存中来帮助最大限度地减少内存使用量。