如何通过有效地节省内存使用来在两个2D numpy数组的每个元素之间执行XOR?

knsnq2tg  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(40)

我不熟悉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:无法为具有形状(2788,1813,203769)和数据类型uint8的数组分配959. GiB
如何通过使用更少的内存来实现这一点?
为了澄清这个问题,下面是我对维度为(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]]

9vw9lbht

9vw9lbht1#

通过使用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参数决定了一次处理多少行。您可能需要根据可用内存和数组的大小调整此值。这种方法可以通过处理数组的块而不是一次将整个数组加载到内存中来帮助最大限度地减少内存使用。

相关问题