【问题标题】:I want to check if there are any identical rows in a matrix我想检查矩阵中是否有任何相同的行
【发布时间】:2022-01-27 01:46:57
【问题描述】:

我需要检查包含整数值的矩阵中是否有任何相同的行 例如:

    A = [[ 2  0  0  0  0  0  0] 
        [ 2  3  5  0  0  0  0]
        [ 2  3  0  0  0  0  0]
        [ 2  0  5  7  0  0  0]
        [ 2  0  5  0  8  0 10]
        [ 2  3  5  0  0  9  0]
        [ 0  0  0  7  8  9  0]
        [ 0  0  5  7  8  9  0]
        [ 0  0  0  7  8  9  0]
        [ 0  0  5  0  0  0 10]]

这必须返回: 正确

但在其他例子中:

   B = [[ 2  0  0  0  0  0  0] 
        [ 2  3  5  0  0  0  0]
        [ 2  3  0  0  0  0  0]
        [ 2  0  5  7  0  0  0]
        [ 2  0  5  0  8  0 10]
        [ 2  3  5  0  0  9  0]
        [ 0  0  1  7  8  9  0]
        [ 0  0  5  7  8  9  0]
        [ 0  0  0  7  8  9  0]
        [ 0  0  5  0  0  0 10]]

这必须返回: 错误

【问题讨论】:

  • 这个问题能回答你的问题吗? stackoverflow.com/questions/50883576/…
  • @FranN.J.,上述方法不适用于专门用于比较重复行的 OPs 案例
  • 他们需要在特定轴上执行一些操作。我在下面的答案中添加了一种变体以及不同的方法。

标签: python python-3.x numpy matrix


【解决方案1】:

方法一:使用 np.unique

  1. 您可以在axis=0 上使用np.unique 来获取唯一行。

  2. return_counts=True 将返回每行重复的次数。

  3. 设置条件c>1 并检查是否有任何行与.any() 匹配该条件将为您提供所需的内容。

def is_dup_simple(arr):
    u, c = np.unique(arr, axis=0, return_counts=True)
    return (c>1).any()

print(is_dup_simple(A))
print(is_dup_simple(B))
True
False

方法 2:广播

这是您可以通过广播操作执行此操作的方法。它的方法稍长,但让您可以非常灵活地使用该方法(例如,在不同数组之间查找重复项)

def is_dup(arr):
    mask = ~np.eye(arr.shape[0], dtype=bool)
    out = ((arr[None,:,:] == arr[:,None,:]).all(-1)&mask).any()
    return out

print(is_dup(A))
print(is_dup(B))
True
False

一步一步的广播表-

arr[None,:,:] -> 1 , 10, 7 (adding new first axis)
arr[:,None,:] -> 10, 1 , 7 (adding new second axis)
--------------------------
     ==       -> 10, 10, 7 (compare elements row-wise)
   all(-1)    -> 10, 10    (compare rows x rows)
   & mask     -> 10, 10    (diagonals false)
   any()      -> 1         (reduce to single bool)
--------------------------

解释

  1. 从 10,7 数组(10 行,7 列)中,您希望匹配元素,最终得到一个 (10,10) 矩阵,其布尔值指示 7 行中的所有元素是否匹配 ANY任何其他行中的元素。

  2. mask = ~np.eye(arr.shape[0], dtype=bool) 特别是一个 10,10 形状的矩阵,沿对角线具有错误值。这样做的原因是,因为您想忽略将行与自身进行比较。稍后再详细介绍。

  3. 从广播的布尔运算开始 - (arr[None,:,:] == arr[:,None,:])。这会产生一个 10,10,7 布尔数组,它将每一行的元素与所有其他行进行比较(10 x 10 比较,7 个值匹配)。

  4. 现在,使用.all(-1),您可以减少最后一个轴并得到一个包含 True 的 10,10 矩阵,如果所有 7 个元素都与任何其他行匹配,否则即使单个元素不同,也为 false。

  5. 接下来,正如您所意识到的,第 0 行将始终与第 0 行匹配,第 1 行也将与第 1 行匹配。因此,该矩阵中的对角线将始终为真。为了推断是否存在重复行,我们必须忽略对角线的 True 值。这可以通过在掩码(上面讨论过)和 10,10 布尔数组之间进行&(和)操作来完成。因此发生的唯一变化是对角线元素变为 False 而不是 True。

  6. 最后,您可以使用.any() 将数组简化为单个布尔值,如果新的 10,10 矩阵中的单个元素为 True(这表示存在与行 y 匹配的行 x正是 AND 行 x 与行 y 不同,这要归功于掩码)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 2013-01-29
    • 2012-04-11
    • 2021-04-11
    • 1970-01-01
    • 2019-06-10
    相关资源
    最近更新 更多