新的较小的数组,不包括每列的一个值

时间:2013-09-19 11:44:42

标签: python arrays numpy matrix

在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)]将是我想要排除的数据的另一个例子。因此,每次循环该函数时,它都会将数组行大小减少一个。我想我必须使用一个蒙面数组或将我的掩码转换为一个蒙版数组并减去两个然后可能压缩输出但我不知道如何。谢谢你的时间。

4 个答案:

答案 0 :(得分:5)

如果在拆开的1-D阵列中转换2-D阵列,则可以非常有效地执行此操作。然后使用要排除的元素重复数组,称为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

答案 1 :(得分:1)

从矩阵e中排除向量a

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()

答案 2 :(得分:1)

这需要一些工作来概括,但这里可以处理你描述的那种二维案例。如果传递意外输入,这将不会注意到并将产生奇怪的结果,但它至少是一个起点:

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优秀的答案部分避免了这个问题,但除非您确定列中没有重复的值,否则不保证任何基于价值的方法都能正常工作。

答案 3 :(得分:1)

本着@ 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]])