检查生成的矩阵是否已经存在

Check, if generated matrix already exists

对于一个机器学习项目,我生成随机矩阵。一个尚不存在的新矩阵存储在数组中。如果创建的矩阵已经存在,则不应添加它。到目前为止,我使用循环和 numpy 的 allclose 函数来将数组中的每个矩阵与实际创建的随机矩阵进行比较。但是我需要 500000 个矩阵,他的代码会花费相应的时间。 您知道比较矩阵与数组中每个矩阵的更好解决方案吗? 如果有任何帮助,我将不胜感激。 这是我的实际代码:

import numpy as np
 
a_total = np.zeros((1,3,3))
while j < 500000:
    atol = 1e-06
    h = 0
    a_add = np.random.rand(3,3).reshape(1,3,3)
    for y in range(a_total.shape[0]):
        mask = np.allclose(a_total[y], a_add, atol)
        if mask == False:
            h+=1
    if (h==a_total.shape(0)):
        a_total = np.concatenate((a_total, a_add), axis=0)
        j=+1

我假设随机数组只是为了示例,因为在 9 元素数组的 n=500000 个条目中获得单个重复项的概率是 1e-6**9*n**2 = 1e-43,这几乎是零小.

如果您的代码似乎永远 运行,那是因为这一行:

    j=+1

应该是 j += 1。还有,这个:

    a_total = np.concatenate((a_total, a_add), axis=0)

是一个缓慢的操作 - 它会复制整个数组。相反,您应该预分配。

最有效的方法是从您的数组创建散列或可散列对象并存储它们。

import numpy as np
n = 500000
 
a_total = np.zeros((n, 3, 3))
seen = set()
j = 0
atol=1e-6
q = int(0.5/atol)

while j < n:
    a_add = np.random.rand(3,3)
        
    a_int = (a_add * q).astype(np.int32).ravel()
    a_bytes = a_int.tobytes()
    if a_bytes in seen:
        continue
    seen.add(a_bytes)
    a_total[j, :, :] = a_add
    j += 1

这将在几秒钟后 运行。这并不完全等同于您的要求,因为 atol=1e-6、1.9e-6 和 2.1e-6(差异 0.2e-6)将被视为不同,而 2.1e-6 和 3.9e-6 (差异 1.8e-6)将被视为相同。但也许这对您的应用程序来说是可以接受的。

如果 seen 的内存有问题,您可以考虑使用 hash(a_bytes),这是一个 8 字节的散列(相比之下,存储整个数组需要 36 个字节)。我怀疑 3x3 数组是否值得麻烦,但如果您的实际用例具有更大的数组,您可以考虑它。