检查张量中任意两个样本是否相同的 Numpy 方法
Numpy way to check if any two samples in a tensor are identical
一些示例:
import numpy as np
tensor_same = np.array([[1]*10 + [2] * 10 + [1] * 10]).reshape((-1, 10, 1))
tensor_diff = np.array([[1]*10 + [2] * 10 + [1] * 9 + [2]]).reshape((-1, 10, 1))
第一个张量有两个相同的样本。在第二个中,所有样本都不同。
检查非常大的张量的最快方法是什么?
我们可以沿第一个轴使用 np.unique
来获得唯一数量的块,如果它与原始输入中的元素数量相同,则表示所有不同的样本,否则至少有一个重复,例如所以-
In [25]: len(np.unique(tensor_same,axis=0)) != len(tensor_same)
Out[25]: True
In [26]: len(np.unique(tensor_diff,axis=0)) != len(tensor_diff)
Out[26]: False
另一种方法是使用 np.unique
-
返回的计数
In [42]: (np.unique(tensor_same,axis=0, return_counts=1)[1]>1).any()
Out[42]: True
In [43]: (np.unique(tensor_diff,axis=0, return_counts=1)[1]>1).any()
Out[43]: False
另一种方法是沿第一个轴排序,执行连续元素微分,然后沿第二个轴查找所有零,最后 ANY
匹配 -
In [29]: (np.diff(np.sort(tensor_same,axis=0),axis=0)==0).all(1).any()
Out[29]: True
In [30]: (np.diff(np.sort(tensor_diff,axis=0),axis=0)==0).all(1).any()
Out[30]: False
另一种方法是使用 views
这样每个 2D
块都被视为一个元素,然后我们使用相同的排序并寻找相同的连续元素,就像这样 -
# @Divakar
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()
def is_any_identical(a):
a1D = view1D(a.reshape(a.shape[0],-1))
a1Ds = np.sort(a1D)
return (a1Ds[:-1] == a1Ds[1:]).any()
样本运行-
In [90]: np.random.seed(0)
...: a = np.random.randint(11,99,(6,4,3))
In [91]: is_any_identical(a)
Out[91]: False
In [92]: a[2] = a[1] # force one identical element
In [93]: is_any_identical(a)
Out[93]: True
对于正 ints
,或者我们可以使用 np.einsum
来获得相同的降维效果,并最终得到一个 2D
块的每个元素。因此,我们将在 is_any_identical()
中得到 a1D
等价物 -
a1D = np.einsum('ijk,jk->i',a,a.max(0)+1)
一些示例:
import numpy as np
tensor_same = np.array([[1]*10 + [2] * 10 + [1] * 10]).reshape((-1, 10, 1))
tensor_diff = np.array([[1]*10 + [2] * 10 + [1] * 9 + [2]]).reshape((-1, 10, 1))
第一个张量有两个相同的样本。在第二个中,所有样本都不同。
检查非常大的张量的最快方法是什么?
我们可以沿第一个轴使用 np.unique
来获得唯一数量的块,如果它与原始输入中的元素数量相同,则表示所有不同的样本,否则至少有一个重复,例如所以-
In [25]: len(np.unique(tensor_same,axis=0)) != len(tensor_same)
Out[25]: True
In [26]: len(np.unique(tensor_diff,axis=0)) != len(tensor_diff)
Out[26]: False
另一种方法是使用 np.unique
-
In [42]: (np.unique(tensor_same,axis=0, return_counts=1)[1]>1).any()
Out[42]: True
In [43]: (np.unique(tensor_diff,axis=0, return_counts=1)[1]>1).any()
Out[43]: False
另一种方法是沿第一个轴排序,执行连续元素微分,然后沿第二个轴查找所有零,最后 ANY
匹配 -
In [29]: (np.diff(np.sort(tensor_same,axis=0),axis=0)==0).all(1).any()
Out[29]: True
In [30]: (np.diff(np.sort(tensor_diff,axis=0),axis=0)==0).all(1).any()
Out[30]: False
另一种方法是使用 views
这样每个 2D
块都被视为一个元素,然后我们使用相同的排序并寻找相同的连续元素,就像这样 -
# @Divakar
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()
def is_any_identical(a):
a1D = view1D(a.reshape(a.shape[0],-1))
a1Ds = np.sort(a1D)
return (a1Ds[:-1] == a1Ds[1:]).any()
样本运行-
In [90]: np.random.seed(0)
...: a = np.random.randint(11,99,(6,4,3))
In [91]: is_any_identical(a)
Out[91]: False
In [92]: a[2] = a[1] # force one identical element
In [93]: is_any_identical(a)
Out[93]: True
对于正 ints
,或者我们可以使用 np.einsum
来获得相同的降维效果,并最终得到一个 2D
块的每个元素。因此,我们将在 is_any_identical()
中得到 a1D
等价物 -
a1D = np.einsum('ijk,jk->i',a,a.max(0)+1)