【问题标题】:remove some elements from a matrix according to the indices根据索引从矩阵中删除一些元素
【发布时间】:2021-11-01 21:27:53
【问题描述】:

我有一个矩阵:

a = ([[1, 0, 0, 0],
       [0, 0, 1, 1],
       [0, 1, 0, 1]
       [1, 0, 0, 1]])

我想打印矩阵中的 0,但不是所有的 0。我只想在具有最小索引的每一行中保留 0,并删除该行中所有后续的零。 例如,在该矩阵的第一行中,应保留第二个元素 (a[0][1]),而应删除第一行中的其余元素,因为它们全为零。

我将pop() 用于二维数组,但出现属性错误。而且输出也不正确。我不知道如何比较索引并选择每一行中最小的列索引。

这是我的代码:

for ix, row in enumerate(a):
  for iy, i in enumerate(row):
    if i==0 and (iy+ix<(iy+1)+ix) :
        a[ix].pop((iy+1))
        print(ix,iy)
    elif i==0 and (iy+ix>(iy+1)+ix):
        a[ix].pop(iy)
        print(ix,iy+1)
print(a)

我的预期结果是一组索引和修改后的矩阵 a。

0 1

1 0

2 0

3 1

a=[[1,0],[0,1,1],[0,1,1],[1,0]]

谁能帮帮我?

【问题讨论】:

  • 你能包括你的预期结果吗?
  • 当然。我编辑了帖子。 @MichaelSzczesny
  • 你使用的是 numpy 还是没有?标签说一件事,编码另一件事......
  • 是的,我使用它。这段代码只是我想找到一种获取输出的方法。我也尝试过 numpy 甚至 pandas。我在标签中提到了 numpy 来询问是否有 numpy 的任何帮助。现在我也在为我程序的其他部分编写你的 numpy 代码。这对我帮助很大。谢谢你。 @MadPhysicist

标签: python arrays python-3.x matrix numpy-ndarray


【解决方案1】:

此解决方案仅在每行至少有一个零时才有效。

indices = []
for x,row in enumerate(a):
    i = row.index(0)
    indices.append((x,i))
    a[x] = row[:i+1] + [e for e in row[i:] if e]

print(indices)
print(a)

输出

[(0, 1), (1, 0), (2, 0), (3, 1)]
[[1, 0], [0, 1, 1], [0, 1, 1], [1, 0, 1]]

【讨论】:

    【解决方案2】:

    假设每一行都有一个零,你可以得到它的列索引

    c = np.argmin(a, axis=1)
    

    或者,如果矩阵可以包含负数,你可以这样做

    c = np.argmax(np.equal(a, 0), axis=1)
    

    行只是

    r = np.arange(len(a))
    

    你想要的结果是那么

    result = np.stack((r, c), axis=-1)
    

    如果其中有没有零的行,您可以使用掩码过滤结果:

    mask = np.array(a)[r, c] == 0
    result = result[mask, :]
    

    【讨论】:

      【解决方案3】:

      查看您的示例输入

      a = [[1,0,0,0],[0,0,1,1],[0,1,0,1],[1,0,0,1]]

      和预期的输出 &gt;&gt;[(0, 1), (1, 0), (2, 0), (3, 1)]

      您可以将问题重新定义为在每一行中找到值为零的元素的索引(如果存在多个元素,则返回第一个)。

      通过这种方式,解决方案很简单,只需遍历a 的每一行并检索值0index(默认情况下只会返回第一个元素)。

      使用如下所示的列表推导:

      value_to_find = 0
      desired_indexes = [
        row.index(value_to_find) for row in a
      ]
      

      或使用map

      value_to_find = 0
      desired_indexes = map(lambda row:row.index(value_to_find), a)
      

      然后您可以枚举它们以将结果与行号配对

      enumerate(desired_indexes)
      

      瞧! &gt;&gt;[(0, 1), (1, 0), (2, 0), (3, 1)]

      整个解决方案可以像这样写在一行中:

      answer = list(enumerate(map(lambda row:row.index(0), a)))
      

      【讨论】:

      • 非常感谢。
      • @exocytosis - 修改矩阵 a 不是您问题的必要部分吗?
      • 是的,确实如此。这是必要的,但我认为我不能同时拥有两个输出,我正在考虑其他解决方案来修改矩阵,不幸的是我做不到。 :)) @MichaelSzczesny
      【解决方案4】:

      试试这个:

      a = [[1, 0, 0, 0],
             [0, 0, 1, 1],
             [0, 1, 0, 1],
             [1, 0, 0, 1]]
      
      b = []
      for i in a:
          f = False
          c = []
          for j in i:
              if (j==0 and f==False) or j != 0:
                  c.append(j)
                  if j == 0: f = True
              else:
                  continue
          b.append(c)
      

      输出:

      [[1, 0], [0, 1, 1], [0, 1, 1], [1, 0, 1]]
      

      要在数组中获取索引zero,您可以试试这个:

      list({i : j.index(0) for i,j in enumerate(b)}.items())
      # [(0, 1), (1, 0), (2, 0), (3, 1)]
      

      【讨论】:

      • 谢谢。但是因为这段代码是一个大程序的一部分,所以我也需要索引。
      • @exocytosis 你说you need indices是什么意思
      • 在问题帖子中,包含预期的输出。我需要具有最小列的每一行中的零索引。
      • @exocytosis 我编辑答案并为您添加此行:list({i : j.index(0) for i,j in enumerate(b)}.items())。这是你的答案吗?
      • 是的……谢谢。
      猜你喜欢
      • 2012-04-15
      • 1970-01-01
      • 2019-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      相关资源
      最近更新 更多