【问题标题】:New array of smaller size excluding one value from each column较小尺寸的新数组不包括每列中的一个值
【发布时间】:2013-09-19 11:44:41
【问题描述】:

在 Python 2.7 中使用 numpy 或任何方式,如果我有一个任意大小的数组并且想要排除某些值并输出新数组,我该怎么做?这是我想要的

[(1,2,3),                                        
 (4,5,6), then exclude [4,2,9] to make the array[(1,5,3),
 (7,8,9)]                                        (7,8,6)]

我将始终排除与行长度相同长度的数据,并且每列始终只有一个条目。 [(1,5,3)] 是我想排除的另一个数据示例。因此,每次我循环该函数时,它都会将数组行大小减一。我想我必须使用掩码数组或将掩码转换为掩码数组并减去两者,然后可能会压缩输出,但我不知道如何。谢谢你的时间。

【问题讨论】:

  • Alfe 实际上给了我我想要的东西。非常感谢你们,我学到了很多!

标签: python arrays numpy matrix


【解决方案1】:

如果您将二维数组转换为未分解的一维数组,则可以非常有效地完成此操作。然后使用要排除的元素重复数组,称为e,以便进行元素比较:

import numpy as np
a = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])
e = [1, 5, 3]    

ar = a.T.ravel()
er = np.repeat(e, a.shape[0])

ans = ar[er != ar].reshape(a.shape[1], a.shape[0]-1).T

但如果e 中的每个元素只匹配a 的一行,它就会起作用。


编辑: 正如@Jaime 所建议的,您可以避免使用ravel() 并直接获得相同的结果:

ans = a.T[(a != e).T].reshape(a.shape[1], a.shape[0]-1).T

【讨论】:

  • 如果您跳过拆解和重复,而只是简单地做ans = a[a != e].reshape(a.shape[0]-1, a.shape[1]),广播不会发挥它的魔力吗?无论如何,不​​错的方法。
  • @Jaime,不。试试看 - 订单出现乱码。广播的魔力仅此而已!在这种情况下,要删除的位置的不规则性意味着如果您这样做,则不会保留列长度。
  • @SaulloCastro,奇怪,我测试过它并没有用。我很想看看我们做了什么不同的...
  • @senderle 我已经更新了答案......所以你可以检查我的方法
  • 仍然对我不起作用。 (ans == a[a!=e].reshape(a.shape[0]-1, a.shape[1])).all() 返回False
【解决方案2】:

从矩阵a中排除向量e

import numpy as np
a = np.array([(1,2,3), (4,5,6), (7,8,9)])
e = [4,2,9]
print np.array([ [ i for i in a.transpose()[j] if i != e[j] ]
    for j in range(len(e)) ]).transpose()

【讨论】:

    【解决方案3】:

    这需要一些工作才能概括,但这里有一些可以处理您描述的那种二维情况的东西。如果传递了意外的输入,这不会注意到并会产生奇怪的结果,但它至少是一个起点:

    def columnwise_compress(a, values):
        a_shape = a.shape
        a_trans_flat = a.transpose().reshape(-1)
        compressed = a_trans_flat[~numpy.in1d(a_trans_flat, values)]
        return compressed.reshape(a_shape[:-1] + ((a_shape[0] - 1),)).transpose()
    

    测试:

    >>> columnwise_compress(numpy.arange(9).reshape(3, 3) + 1, [4, 2, 9])
    array([[1, 5, 3],
           [7, 8, 6]])
    >>> columnwise_compress(numpy.arange(9).reshape(3, 3) + 1, [1, 5, 3])
    array([[4, 2, 6],
           [7, 8, 9]])
    

    困难在于您要求“压缩”numpy.compress 不这样做(删除每列或每行的不同值)并且您要求压缩沿着列而不是行。沿行压缩更容易,因为它沿内存中值的自然顺序移动;出于这个原因,您可能会考虑使用转置数组。如果你想这样做,事情就会变得简单一些:

    >>> a = numpy. array([[1, 4, 7],
    ...                   [2, 5, 8],
    ...                   [3, 6, 9]])
    >>> a[~numpy.in1d(a, [4, 2, 9]).reshape(3, 3)].reshape(3, 2)
    array([[1, 7],
           [5, 8],
           [3, 6]])
    

    如果你这样做,你仍然需要智能地处理形状参数,但它仍然会更简单。此外,这假设原始数组中没有重复项;如果有,这可能会产生错误的结果。 Saullo 的出色回答部分避免了该问题,但任何基于值的方法都不能保证有效,除非您确定列中没有重复值。

    【讨论】:

      【解决方案4】:

      本着@SaulloCastro 回答的精神,但要处理多次出现的项目,您可以执行以下操作删除每列的第一次出现:

      def delete_skew_row(a, b) :
          rows, cols = a.shape
          row_to_remove = np.argmax(a == b, axis=0)
          items_to_remove = np.ravel_multi_index((row_to_remove,
                                                  np.arange(cols)),
                                                 a.shape, order='F')
          ret = np.delete(a.T, items_to_remove)
          return np.ascontiguousarray(ret.reshape(cols,rows-1).T)
      
      rows, cols = 5, 10
      a = np.random.randint(100, size=(rows, cols))
      b = np.random.randint(rows, size=(cols,))
      b = a[b, np.arange(cols)]
      
      >>> a
      array([[50, 46, 85, 82, 27, 41, 45, 27, 17, 26],
             [92, 35, 14, 34, 48, 27, 63, 58, 14, 18],
             [90, 91, 39, 19, 90, 29, 67, 52, 68, 69],
             [10, 99, 33, 58, 46, 71, 43, 23, 58, 49],
             [92, 81, 64, 77, 61, 99, 40, 49, 49, 87]])
      >>> b
      array([92, 81, 14, 82, 46, 29, 67, 58, 14, 69])
      >>> delete_skew_row(a, b)
      array([[50, 46, 85, 34, 27, 41, 45, 27, 17, 26],
             [90, 35, 39, 19, 48, 27, 63, 52, 68, 18],
             [10, 91, 33, 58, 90, 71, 43, 23, 58, 49],
             [92, 99, 64, 77, 61, 99, 40, 49, 49, 87]])
      

      【讨论】:

        猜你喜欢
        • 2013-04-28
        • 2019-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-02
        • 1970-01-01
        • 2014-04-24
        相关资源
        最近更新 更多