3

在 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

4 回答 4

5

如果您将二维数组转换为未分解的一维数组,则可以非常有效地完成此操作。然后使用要排除的元素重复数组,调用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
于 2013-09-19T12:54:15.797 回答
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()
于 2013-09-19T12:46:43.013 回答
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的出色回答部分避免了该问题,但除非您确定列中没有重复值,否则任何基于值的方法都不能保证有效。

于 2013-09-19T12:47:33.033 回答
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]])
于 2013-09-19T15:16:12.020 回答