【问题标题】:Check, if generated matrix already exists检查生成的矩阵是否已经存在
【发布时间】:2020-07-02 10:01:02
【问题描述】:

对于机器学习项目,我生成随机矩阵。一个尚不存在的新矩阵存储在一个数组中。如果创建的矩阵已经存在,则不应添加。到目前为止,我使用循环和 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

【问题讨论】:

  • 一个建议是在完整的元素检查之前使用不太严格的检查,例如,只检查矩阵的第一个元素的相等性(直到一个容差),并且只有当它不同时, 执行完整的元素检查以确保所有元素在附加之前都不同
  • 如果这是用于某种蒙特卡罗模拟,但我确实想知道为什么您会摆脱与早期场景相同的场景,因为这会改变您尝试模拟的过程的统计属性- 我知道这不是你的问题,所以只是一个想法......
  • 在您的代码中添加一个变量 'a = 8.0000001'。生成矩阵后,计算矩阵之和。然后将矩阵的任何一个元素更改为“a-sum”。然后将 a 递增为 'a+=0.00000001' 并继续。这样,您的所有矩阵都将是唯一的。根据矩阵的数量,您可以在 8.00000001 中添加更多或更少的零.....
  • 确保您使用的是 float64 值

标签: python arrays numpy matrix data-generation


【解决方案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 数组的麻烦是否值得,但如果您的实际用例有更大的数组,您可以考虑这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    • 2012-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多