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

问题描述 投票:0回答:1

我不熟悉 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]]
python numpy bit-manipulation
1个回答
-4
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.