【问题标题】:find and delete from more-dimensional numpy array从多维 numpy 数组中查找和删除
【发布时间】:2013-05-30 14:50:11
【问题描述】:

我有两个 numpy 数组:

p_a_colors=np.array([[0,0,0],
                     [0,2,0],
                     [119,103,82],
                     [122,122,122],
                     [122,122,122],
                     [3,2,4]])

p_rem = np.array([[119,103,82],
                     [122,122,122]])

我想从 p_a_colors 中删除 p_rem 中的所有列,所以我得到:

p_r_colors=np.array([[0,0,0],
                    [0,2,0],
                    [3,2,4]])

我认为,应该像这样工作

p_r_colors= np.delete(p_a_colors, np.where(np.all(p_a_colors==p_rem, axis=0)),0)

但我只是没有得到正确的轴或 [:]。

我知道,那个

p_r_colors=copy.deepcopy(p_a_colors)
for i in range(len(p_rem)):
    p_r_colors= np.delete(p_r_colors, np.where(np.all(p_r_colors==p_rem[i], axis=-1)),0)

会起作用,但我试图避免(python)循环,因为我也想要正确的性能。

【问题讨论】:

  • 等一下。这段代码应该做什么?
  • 它应该给我一个新的 numpy.array p_r_colors,它是 p_a_colors-p_rem,与其他 2 个数组的形状相同

标签: python arrays numpy


【解决方案1】:

我会这样做:

dtype = np.dtype((np.void, (p_a_colors.shape[1] * 
                            p_a_colors.dtype.itemsize)))
mask = np.in1d(p_a_colors.view(dtype), p_rem.view(dtype))
p_r_colors = p_a_colors[~mask]

>>> p_r_colors
array([[0, 0, 0],
       [0, 2, 0],
       [3, 2, 4]])

您需要执行 void dtype 操作,以便 numpy 将行作为一个整体进行比较。之后,使用内置的 set 例程似乎是显而易见的方法。

【讨论】:

    【解决方案2】:

    很丑,但是

    tmp = reduce(lambda x, y: x |  np.all(p_a_colors == y, axis=-1), p_rem, np.zeros(p_a_colors.shape[:1], dtype=np.bool))
    
    indices = np.where(tmp)[0]
    
    np.delete(p_a_colors, indices, axis=0)
    

    (编辑:更正)

    >>> tmp = reduce(lambda x, y: x |  np.all(p_a_colors == y, axis=-1), p_rem, np.zeros(p_a_colors.shape[:1], dtype=np.bool))
    >>> 
    >>> indices = np.where(tmp)[0]
    >>> 
    >>> np.delete(p_a_colors, indices, axis=0)
    array([[0, 0, 0],
           [0, 2, 0],
           [3, 2, 4]])
    >>> 
    

    【讨论】:

      【解决方案3】:

      您弄错了索引。表达式p_a_colors==p_rem 计算结果为一个空数组,因为这两个数组永远不会相等(它们具有不同的形状!)。如果你想使用np.delete,你需要一个更正确的索引列表。

      另一方面,这可以通过索引更轻松地完成:

      >>> idx = np.array([p_a_colors[i] not in p_rem for i in
                          range(p_a_colors.shape[0])], dtype='bool')
      >>> p_a_colors[idx]
      array([[0, 0, 0],
             [0, 2, 0],
             [3, 2, 4]])
      

      或者,受@Jaime 建议的启发,您也可以使用np.in1d 创建索引,在一行中:

      >>> idx = ~np.all(np.in1d(p_a_colors, p_rem).reshape(p_a_colors.shape), 
                        axis=1)
      >>> p_a_colors[idx]
      array([[0, 0, 0],
             [0, 2, 0],
             [3, 2, 4]])
      

      如果您必须使用np.delete,只需将索引列表从bool 转换为序列:

      >>> idx = np.array([p_a_colors[i] in p_rem for i in 
                                range(p_a_colors.shape[0])])
      >>> idx = np.arange(p_a_colors.shape[0])[idx]
      >>> np.delete(p_a_colors, idx, axis=0)
      array([[0, 0, 0],
             [0, 2, 0],
             [3, 2, 4]])
      

      【讨论】:

      • 出了点问题。我用大型数组尝试过,它删除了很多。
      • 您尝试了哪个版本?数组的维度是否超过 2 个?
      • 我做了第二个版本。没有一切都应该是相同的,但具有更多的价值。我已经实现了 Jaime 的版本。这似乎工作正常。
      • 原因~np.all(np.in1d(p_a_colors, p_rem).reshape(p_a_colors.shape),axis=1) 给出的结果不正确是它只是说(在否定之前)给定行的所有成员都在另一个数组中,但不一定在同一行中。
      猜你喜欢
      • 1970-01-01
      • 2021-09-17
      • 2017-04-11
      • 1970-01-01
      • 2015-06-08
      • 1970-01-01
      • 1970-01-01
      • 2021-03-26
      • 2016-09-06
      相关资源
      最近更新 更多