使用更少的内存在两个矩阵之间执行异或运算的最有效方法

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

我想通过节省内存使用来在两个 2D numpy.ndarray 之间执行 XOR 运算。对于u_values的每一行,我想对v_values的每一行执行异或运算,依此类推。例如,如果 u_values 的维度为 (8,10) 并且 v_values 的维度为 (6,10),则结果最终的维度将为 (48, 10)

这是一个例子:

import numpy as np

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]])

#What I have tried so far:
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]))

这就是我得到的尺寸为 (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]]

我想要的最终结果是一个行列表,其中每行包含 True 值的索引

final_results = [np.nonzero(row)[0] + 1 for row in xor_results]

用一个小例子就可以很好地工作。然而,对于我的真实情况,我遇到了一个非常巨大的 2D numpy.ndarray ,其中 u_values 的大小为 (2788, 203769)v_values 的大小为 (1813, 203769)

我的 XOR 运算内存不足:

numpy.core._exceptions.MemoryError:无法为形状为 (2788, 1813, 203769) 和数据类型为 uint8 的数组分配 959.GiB

我想知道是否有一种更直接、更快速的方法来通过处理此类问题来加速此过程,以便获得上述所需结果的列表(即final_results),而无需计算如此昂贵的费用?

python numpy bit-manipulation numpy-ndarray numba
1个回答
0
投票

我会为此编写一个生成器函数。

def linewise_xor(u_values, v_values):
    i, k = u_values.shape
    j, k = v_values.shape
    for idx in range(j):
        xor_results = u_values ^ v_values[idx]
        yield [np.nonzero(row)[0] + 1 for row in xor_results]

这将生成与

u_values
的形状相关的结果块,但不会生成任何大到你的记忆无法处理的内容。您可以按顺序处理这些。

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