Python 如何散列numpy数组以检查重复项
我已经搜索了一些教程等,以帮助解决这个问题,但似乎找不到任何东西 我有两个n维numpy数组列表(一些图像的3D数组形式),我想检查每个列表中的重叠图像。让我们说列表a是一个训练集,列表b是一个验证集。 一种解决方案是使用嵌套循环,并使用Python 如何散列numpy数组以检查重复项,python,arrays,numpy,hash,Python,Arrays,Numpy,Hash,我已经搜索了一些教程等,以帮助解决这个问题,但似乎找不到任何东西 我有两个n维numpy数组列表(一些图像的3D数组形式),我想检查每个列表中的重叠图像。让我们说列表a是一个训练集,列表b是一个验证集。 一种解决方案是使用嵌套循环,并使用np.array(a[i],b[j])检查每对数组是否相等,但这很慢(每个列表中大约有200000个numpy数组),坦白说,这相当令人厌恶 我在想实现这一点的一种更优雅的方法是对每个列表中的每个numpy数组进行散列,然后使用这些散列表比较每个条目 首先,此解
np.array(a[i],b[j])
检查每对数组是否相等,但这很慢(每个列表中大约有200000个numpy数组),坦白说,这相当令人厌恶
我在想实现这一点的一种更优雅的方法是对每个列表中的每个numpy数组进行散列,然后使用这些散列表比较每个条目
首先,此解决方案正确吗?其次,我将如何实现此目标?下面是一些数据的示例
train_dataset[:3]
array([[[-0.5 , -0.49607843, -0.5 , ..., -0.5 ,
-0.49215686, -0.5 ],
[-0.49607843, -0.47647059, -0.5 , ..., -0.5 ,
-0.47254902, -0.49607843],
[-0.49607843, -0.49607843, -0.5 , ..., -0.5 ,
-0.49607843, -0.49607843],
...,
[-0.49607843, -0.49215686, -0.5 , ..., -0.5 ,
-0.49215686, -0.49607843],
[-0.49607843, -0.47647059, -0.5 , ..., -0.5 ,
-0.47254902, -0.49607843],
[-0.5 , -0.49607843, -0.5 , ..., -0.5 ,
-0.49607843, -0.5 ]],
[[-0.5 , -0.5 , -0.5 , ..., 0.48823529,
0.5 , 0.1509804 ],
[-0.5 , -0.5 , -0.5 , ..., 0.48431373,
0.14705883, -0.32745099],
[-0.5 , -0.5 , -0.5 , ..., -0.32745099,
-0.5 , -0.49607843],
...,
[-0.5 , -0.44901961, 0.1509804 , ..., -0.5 ,
-0.5 , -0.5 ],
[-0.49607843, -0.49607843, -0.49215686, ..., -0.5 ,
-0.5 , -0.5 ],
[-0.5 , -0.49607843, -0.48823529, ..., -0.5 ,
-0.5 , -0.5 ]],
[[-0.5 , -0.5 , -0.5 , ..., -0.5 ,
-0.5 , -0.5 ],
[-0.5 , -0.5 , -0.5 , ..., -0.5 ,
-0.5 , -0.5 ],
[-0.5 , -0.5 , -0.49607843, ..., -0.5 ,
-0.5 , -0.5 ],
...,
[-0.5 , -0.5 , -0.5 , ..., -0.48823529,
-0.5 , -0.5 ],
[-0.5 , -0.5 , -0.5 , ..., -0.5 ,
-0.5 , -0.5 ],
[-0.5 , -0.5 , -0.5 , ..., -0.5 ,
-0.5 , -0.5 ]]], dtype=float32)
我提前感谢您的帮助。您可以使用numpy(一维集相交)功能在阵列之间找到重复项
duplicate_images = np.intersect1d(train_dataset, test_dataset)
我使用训练集和测试集(分别为55000和10000个数组)对此进行计时,我猜其中一个数组和您的数据类似。使用intersect1d,在我的机器上完成大约需要2.4秒(参数为假设_unique=True
,只需要1.3秒)。像你描述的两两比较花了几分钟
编辑
正如@mbhall88在评论中指出的那样,这个答案(如上)并不比较每个“图像”数组,而是比较数组中的元素,而不是数组本身。为了确保它能够比较数组,您仍然可以使用intersect1d
,但您必须首先按照说明处理数据类型。但是,该答案中的示例涉及二维阵列,因为您使用的是三维阵列,所以应该首先展平第二个二维。您应该能够执行以下操作:
def intersect3d(A,B, assume_unique=False):
# get the original shape of your arrays
a1d, a2d, a3d = A.shape
# flatten the 2nd and 3rd dimensions in your arrays
A = A.reshape((a1d,a2d*a3d))
B = B.reshape((len(B),a2d*a3d))
# define a structured dtype so you can treat your arrays as single "element"
dtype=(', '.join([str(A.dtype)]*ncols))
# find the duplicate elements
C = np.intersect1d(A.view(dtype), B.view(dtype), assume_unique=assume_unique)
# reshape the result and return
return C.view(A.dtype).reshape(-1, ncols).reshape((len(C),a2d,a3d))
该软件包(diclaimer:我是它的作者)有一个高效的单行程序:
import numpy_indexed as npi
duplicate_images = npi.intersection(train_dataset, test_dataset)
加上许多相关函数,您可能会发现这些函数在本文中很有用。想出一些东西并不难: 但请注意:
- 检查浮点相等性通常是个坏主意,因为精度和舍入误差有限。著名的例子:
>>> 0.1 + 0.2 == 0.3 False
- NaN的不可与自己相比:
>>> np.nan == np.nan False
- 上面的简单散列函数考虑浮点数的位表示,但在存在负零和信号NaN的情况下,这是有问题的
另请参见此问题中的讨论:向我们展示一下您在成对比较中所做的工作。我不知道在这种情况下你所说的恶心是什么意思。参见最近的。还可以看看关于唯一行或排序行的问题。基本上我是这样尝试的:
duplicates=[]在train_数据集中为i:在有效的_数据集中为j:duplicates.append(np.equal(i,j)
对于格式设置很抱歉,这些注释很奇怪。np.equal
如何使用浮点数执行?通常我们建议在测试浮点数数组时使用np.allclose
。(或np.isclose
)显然不是很好,因为我让它运行了大约30分钟,但它还没有完成哈哈。我现在将尝试这两个选项。这种方法的问题是它会在数组中找到相同的元素。我感兴趣的是哪些数组是相同的,即数组中的所有元素都完全相同,而不仅仅是一个元素。哟你完全正确。我相信这说明了如何按你需要的方式使用intersect1d。我也会用链接更新答案。
>>> np.nan == np.nan
False